Django has a ProxyModel. How is this convenient to use and when is it useful?
Proxy model https://docs.djangoproject.com/en/3.0/topics/db/models/#proxy-models
This is just the explanation.
You may want to change only the behavior of Python in your model. We may change the default manager or add new methods.
However, it seems that there are various itchiness, and I am worried about how to use it conveniently. It's just a purposeful means, so I don't want to force it. Right way to return proxy model instance from a base model instance in Django?
Django is a structure that allows you to have multiple applications in your project. A common pattern is to use Django to create an admin screen (a admin tool for people inside, not Django Admin), or DRF to create an API? In such a case, you will often want to use the DB in common for these two apps. For example, large-scale services are converted to microservices, and it may not be divided (managed) in that way, but I think that there are quite a lot of such configurations in startups that want results first and foremost.
When taking such a configuration, it is necessary to use a common model in Django and DRF, but this can be found quite easily by searching, and the system is completed and implemented basically nothing. There is no problem.
Django's ORM is excellent and I rarely have the opportunity to write raw SQL, but I don't think it's okay to write ORM instructions in the view. It's like this.
class MyViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
queryset = schema.MyObject.objects.all().order_by('id')
serializer_class = MyObjectSerializer
What's the difference between this and the old-fashioned do not write SQL in Controller
?
Do you know that it's no good if you make it like this?
class MyViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
queryset = schema.MyObject.objects.filter(type=schema.MyObject.TYPE.OPEN).order_by('id')
serializer_class = MyObjectSerializer
So, I think it's better to write a method in model.
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')
Like this.
For example, the LIST-type QUERY that lists even the logically deleted data required for the Admin application is not required on the API side. If you hit it by mistake rather than unnecessary (it's an implementation mistake), you'll end up with data that you shouldn't show.
__ ProxyModel can be used in such cases. __
It's like this.
Example of how to write ProxyModel
class Article(XModel):
TYPE = Choices(
('DRAFT', 'draft'),
('PUBLISH', 'Now open'),
)
type = StatusField(
choices_name='TYPE',
blank=False,
default=TYPE.DRAFT,
help_text="Article status",
)
text = models.TextField(
null=False,
blank=False,
default="",
help_text="Article content",
)
writer = models.ForeignKey(
to="Account",
related_name="articles",
null=False,
on_delete=models.DO_NOTHING,
help_text="Article writer",
)
class ArticleProxy(ProxyModel, schema.Article):
@classmethod
def list_of_draft(cls):
return cls.objects.filter(type=cls.TYPE.DRAFT)
Please write in this form. The point is cls.objects.filter
. Even if the meaning is the same, if it is schema.Article.objects.filter
, the return value will be an array of ʻArticle` (strictly speaking, it is a QuerySet, not an array).
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
Do you know this is a bug? now () is evaluated only once and is not calculated every time there is a request. The essence of this problem is that methods (or functions in the old way) are essentially black boxes and should be called without knowing their contents. In this example, the View implementer usually says "__ There is a convenient method, let's use it! __".
There is an idea (in me) that even communication is useless in startups that start up businesses at explosive speed. I feel that it is an era when 1on1 is recommended and management is emphasized while changing from spinach to zassou, but at XTech, the organizations that need management are old, each is not a professional, so that's what it is. I think I need. (The longest part of my career is management, but w)
In short, I think that a framework that can be understood without communication even when implementing it, and that if you make it normally, you will not create strange bugs or security holes is important for increasing productivity.
The person who implements each application adds a method on ProxyModel and uses it. You cannot access data that only the administrator can access if you use it normally (unless you write such a method)
There is also a workaround in the case where you write a method in the Model given in the above example and it is used like a black box to step on a bug. I'm wondering if you can imagine this or put it in the next content.
Since it is a scribble, I think there are typographical errors and strange parts, so if you can comment, I will make time to review it!
Recommended Posts