[PYTHON] À propos du ProxyModel de Django

Django a un ProxyModel. Comment est-ce pratique à utiliser et quand est-ce utile?

Modèle proxy https://docs.djangoproject.com/en/3.0/topics/db/models/#proxy-models

Ceci n'est que l'explication.

Vous souhaiterez peut-être modifier uniquement le comportement de Python dans votre modèle. Nous pouvons changer le gestionnaire par défaut ou ajouter de nouvelles méthodes.

Cependant, il semble qu'il existe différents points de démangeaisons et je me demande comment l'utiliser de manière pratique. C'est juste un moyen utile, donc je ne veux pas le forcer. Right way to return proxy model instance from a base model instance in Django?

Pour le moment, qu'en est-il de cette situation?

Django est une structure qui vous permet d'avoir plusieurs applications dans votre projet. Un modèle courant est de créer un écran d'administration avec Django (un outil d'administration pour les personnes à l'intérieur au lieu de Django Admin) et une API avec DRF? Dans de tels moments, vous souhaiterez souvent utiliser la base de données en commun pour ces deux applications. Par exemple, un service à grande échelle est converti en un micro-service, et il peut ne pas être divisé (géré) de cette manière, mais je pense qu'il existe de nombreuses configurations de ce type dans les startups qui veulent avant tout des résultats.

スクリーンショット 2020-02-20 16.33.53.png

Lors de la prise d'une telle configuration, il est nécessaire d'utiliser un modèle commun dans Django et DRF, mais cela peut être trouvé assez facilement en recherchant, et le système est terminé et implémenté pratiquement rien. Il n'y a pas de problème.

Écrivez-vous beaucoup de méthodes dans le modèle?

L'ORM de Django est excellent et j'ai rarement l'occasion d'écrire du SQL brut, mais je ne pense pas que ce soit correct d'écrire des instructions ORM en vue. C'est comme ça.

class MyViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = schema.MyObject.objects.all().order_by('id')
    serializer_class = MyObjectSerializer

Quelle est la différence entre ceci et l'ancien "Ne pas écrire SQL dans Controller"? Savez-vous que ce n'est pas bon si vous faites comme ça?

class MyViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = schema.MyObject.objects.filter(type=schema.MyObject.TYPE.OPEN).order_by('id')
    serializer_class = MyObjectSerializer

Donc, je pense qu'il vaut mieux écrire une méthode en modèle.

class MyViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = schema.MyObject.filter_of_open_object()
    serializer_class = MyObjectSerializer

class MyObject(models.Model):
    @classmethod
    def filter_of_open_object(cls):
        return cls..objects.filter(type=schema.MyObject.TYPE.OPEN).order_by('id')

Comme ça.

Que diriez-vous d'écrire un modèle qui utilise des méthodes qui ne sont pas liées à d'autres applications en commun? ??

Dans l'exemple, la requête de type LIST qui répertorie même les données supprimées logiquement requises pour l'application d'administration n'est pas requise du côté API. Si vous le frappez par erreur plutôt que inutile (c'est une erreur d'implémentation), vous vous retrouverez avec des données que vous ne devriez pas afficher.

__ ProxyModel peut être utilisé dans de tels cas. __

C'est comme ça. スクリーンショット 2020-02-20 16.45.12.png

Remarques sur la méthode Model et ProxyModel

Exemple d'écriture de ProxyModel

class Article(XModel):
    TYPE = Choices(
        ('DRAFT',   'Brouillon'),
        ('PUBLISH', 'Ouvert'),
    )

    type = StatusField(
        choices_name='TYPE',
        blank=False,
        default=TYPE.DRAFT,
        help_text="Statut de l'article",
    )

    text = models.TextField(
        null=False,
        blank=False,
        default="",
        help_text="Contenu de l'article",
    )

    writer = models.ForeignKey(
        to="Account",
        related_name="articles",
        null=False,
        on_delete=models.DO_NOTHING,
        help_text="Rédacteur d'article",
    )

class ArticleProxy(ProxyModel, schema.Article):

    @classmethod
    def list_of_draft(cls):
        return cls.objects.filter(type=cls.TYPE.DRAFT)

Veuillez écrire dans ce formulaire. Le point est cls.objects.filter. Même si la signification est la même, s'il s'agit de schema.Article.objects.filter, la valeur de retour sera un tableau de ʻArticle` (à proprement parler, il s'agit d'un QuerySet, pas d'un tableau).

Remarques sur les méthodes d'écriture dans Model (Proxy)

class ArticleProxy(ProxyModel, schema.Article):

    @classmethod
    def list_of_future(cls):
        return cls.objects.filter(resavation_at=now())


class MyViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = ArticleProxy.list_of_future()
    serializer_class = ArticleSerializer

Savez-vous que c'est un bug? now () n'est évalué qu'une seule fois et n'est pas calculé à chaque fois qu'il y a une demande. L'essence de ce problème est que les méthodes (ou fonctions à l'ancienne) sont essentiellement des boîtes noires et doivent être appelées sans connaître leur contenu. Dans cet exemple, l'implémenteur de View dit généralement "__ Il existe une méthode pratique, utilisons-la! __".

Pourquoi vous en tenez-vous à cela?

Il y a une idée (en moi) que même la communication est inutile dans les startups qui démarrent des entreprises à une vitesse explosive. Je sens que c'est une époque où 1on1 est recommandé et où la gestion est mise en avant en passant de l'épinard au zassou, mais chez XTech, les organisations qui ont besoin de gestion sont anciennes, chacune n'est pas professionnelle, c'est donc le cas. Je pense que j'ai besoin. (La partie la plus longue de ma carrière est la gestion, mais w)

Bref, je pense qu'un framework qui peut être compris sans communication même lors de sa mise en œuvre, et que si vous le faites normalement, vous ne créerez pas d'étranges bugs ou failles de sécurité est important pour augmenter la productivité.

Recommandation du modèle de proxy

La personne qui implémente chaque application ajoute une méthode sur ProxyModel et l'utilise. Vous ne pouvez pas accéder aux données auxquelles seul l'administrateur peut accéder si vous l'utilisez normalement (sauf si vous écrivez une telle méthode)

finalement

Il existe également une solution de contournement dans le cas où vous écrivez une méthode dans le modèle donné dans l'exemple ci-dessus et elle est utilisée comme une boîte noire pour résoudre un bogue. Je me demande si vous pouvez l'imaginer ou le mettre dans le prochain contenu.

Puisqu'il s'agit d'un gribouillage, je pense qu'il y a des erreurs typographiques et des parties étranges, donc si vous pouvez commenter, je prendrai le temps de le revoir!

Recommended Posts

À propos du ProxyModel de Django
À propos de la déconstruction et de la déconstructibilité de Django
À propos de LangID
À propos de CAGR
À propos de python-apt
À propos de l'autorisation
À propos de requirements.txt
À propos des paramètres régionaux
À propos de l'axe = 0, axe = 1
À propos de l'importation
À propos de numpy
À propos de pip
À propos de Linux
À propos d'Endian
À propos de Linux
À propos de l'importation
ImageField de Django
À propos de Linux
À propos de Linux
À propos de cv2.imread
À propos de _ et __
À propos de wxPython
À propos du comportement Model.save () de Django et de l'erreur de blocage MySQL
Parler du transfert des paramètres de tableau vers le QueryDict de django