Is the DRF ModelSerializer faster or slower than the standard Serializer? - django

At work we tend to stay away from using the ModelSerializer in the Django Rest Framework. From what I have heard it is said to be faster in some respects. Is this the case?
And what are the advantages of using the standard serializer instead of the ModelSerializer?

ModelSerializer is used when you need to serialize a model while regular Serializer is used when you need to serialize certain information which might not be a model.
Check this article

Okay, now one of the main reasons that I have heard, after to talking to some people. Is that when it comes to using the ModelView, you have this issue where you have a number of API endpoints that can end up being redundant.
There is also a lot more to take care of too.

Related

Query only specific subclass(es) of an abstract superclass

This question is fundamentally similar to these previous questions:
Django access to subclasses items from abstract class
How to query abstract-class-based objects in Django?
I am posting this as a new, separate question because:
I have minor additional considerations that aren't addressed in the previous questions
The previous questions are relatively old, and if it's the case that the correct answer has changed in recent times, I wonder if maybe those questions haven't been visible enough (given that they have accepted answers) to get the attention of those who might know about such potential changes.
With that in mind, I'll take the question from the top and define it fully and concretely - and I leave it to the hive to determine if a close-duplicate is in order.
Background
Say I am constructing models to represent parts of a building. I split the building into logical classes:
Floor
BuildingSpace(ABC)
Office(BuildingSpace)
CommonArea(BuildingSpace)
Goal
Under Floor, I want methods that can retrieve all buildingspaces - or, either of its two subclasses separately:
from typing import Type
class Floor(models.Model):
def getAllSpaces():
# return all objects that satisfy Type[BuildingSpace]
def getAllOffices():
# return all objects that satisfy strictly and only Type[Office]
def getAllCommonAreas():
# return all objects that satisfy strictly and only Type[CommonArea]
Possible solutions
django-model-utils looks like it can support this kind of a query out-of-the-box with its InheritanceManager and the .select_subclass() method -- but, crucially, requires BuildingSpace to be concrete, so that leaves this solution with having to go with multi-table inheritance. Which I understand amplifies database load for each query, so I looked into making the subclasses proxies in order to mitigate that, but InheritanceManager doesn't support proxies. When all is said and done, django-model-utils look to me like it unavoidably opens me to multi-table inheritance penalties at query time.
django-polymorphic also supports this out-of-the-box as far as I have been able to glean, using .instance_of(subclass). Purely from a coding point-of-view, this approach looks very clean and easy to use. But it also looks to come with database performance considerations, and making it admin-panel compliant looks non-trivial at a first, superficial glance.
Natively, it looks django can do this in some roundabout way, but I've seen claims that achieving the same functionality as described above with a native QuerySet.filter() approach is worse performance-wise than both of the above extensions.
A final alternative solution I've briefly considered, that I assume will work natively without creating database considerations (but does require a slight redesign) - is to access the subclass managers directly, and then have the desired outcome of getAllSpaces() implemented via a QuerySet.Union-type of approach.
Almost-MRE
Naïve setup of how I had imagined to be able to use the code:
class BuildingSpace(models.Model):
floor = models.ForeignKey('Floor',
on_delete=models.CASCADE,
related_name="interiors")
class Meta:
abstract = True
class Floor(models.Model):
def _InteriorManager(self): # get the default manager of BuildingSpace
return self.interiors
def GetAllInteriors(self):
return self._InteriorManager().all() # get the full Type[BuildingSpace] queryset, but this isn't supported in native django
def GetOffices(self):
return self._InteriorManager().instance_of(Office) # django-polymorphic
def GetCommonAreas(self):
return self._InteriorManager().select_subclasses(CommonAreas).all() # django-model-utils
Question
I'm hoping to get answers that can weigh in on the following factors:
is there any significant difference in performance between django-model-utils, django-polymorphic and some other best-case QuerySet.filter()-based approach for the cases described here (and potentially, the linked questions at the top)
does either extension implicate any other consideration that is worth noting (ease of use, extensibility, how additional filtering is done, etc)
would my "final alternative solution" in the end maybe work better on all accounts (performance, ease of use, extensibility) if it is the case that the use-cases I need solved are never more complex than the concrete code examples I've provided
I have no insights as to the database performance topic as of yet, but I will say this:
django-polymorphic is really smooth to use. Minimal code adaptation required, and the syntax is both short and intuitive. The perceived difficulty of making it compliant with the admin-panel was a smokescreen, at least as long as you do basic, straightforward subclassing.
For anyone coming this way with similar troubles, don't hesitate to try it. You can't use it on abstract classes, as mentioned, but unless you have really particular needs it does look like having a concrete superclass and just using this library is a whole lot easier than jerry-rigging a manual solution similar to the one I described in the question.

Can we use same serializer for POST, PUT & GET?

Can we use same serializer for creating, updating and getting a resource. is it a best practice to do so ?
Can we use same serializer for creating, updating and getting a resource.
Why, yes, of course. Even more than that, we can use the exact same serializer for partially updating (PATCH) and deleting (DELETE) a resource.
This is because the serializer doesn't actually "knows" about all of these operations, it only serializes and deserializes data -- it is the view that handles http methods.
is it a best practice to do so ?
It is most definitely not bad practice.
But is it good ? It really depends on what type of behaviour you are expecting for each of these, whether you have nested objects or not, etc.
I would strongly suggest you read more from the docs, especially about ModelSerializer.
Good luck.

Cannot quite get my head around django mixins

I recently had a django question - and one of the answers left me stumped:
https://stackoverflow.com/a/10608687/1061426
I've read the django doco, but cannot quite work out how mixins are relevant to what was asked, or what the answer is referring to.
So, I searched for "django mixin tutorial" and stumbled across something called dajax and dajaxice. Ok, i am lying, i came across this blog:
http://www.pythondiary.com/blog/Apr.15,2012/stay-tuned-django-ajax-tutorial.html
My question is:
What are mixins? How do they relate to ajax calls? Are they used for things other than ajax? Why would i want to use dajax or dajaxice or some other django addin framework, rather than just plain django to work with ajax?
Also, there isn't a dajax tag, but there is a dajaxice tag for stackoverflow... does that mean that dajaxice is The Way To Go?
Cheers,
Mixins are a general Object Oriented Programming concept. They don't specifically have anything to do with Django or Dajax, etc. However, Django does, and Dajax probably as well, use mixins.
In general, a "mixin" is simply a class that is meant to literally be mixed in with another class. It typically doesn't do anything on its own, but rather, merely adds functionality to another class. Django's concept of "abstract" models are an example of a mixin. You never instantiate an abstract model. Instead, other models inherit from the abstract model, gaining all of its functionality, and it's those subclasses that actually are instantiated.
Django's class-based views (which is what the answer that brought you here is talking about) also use mixins. For example, most of the class-based views inherit from TemplateResponseMixin. This class is not a view itself, and you would never use it for anything but for a class-based view to inherit from. It's merely an encapsulation of all the functionality that renders a template into a response, so this functionally can be "mixed in" to all the various views without violating DRY (Don't Repeat Yourself).
No, mixins don't have anything in particular to do with Ajax.
A mixin is just a class that can be used as part of the multiple inheritance for another class. Django uses these extensively in its class-based views - some classes provide (for example) the basic functionality for displaying forms, or lists of models, and you are meant to mix those in with your own classes: create your own code that implements your own extensions to that functionality, while inheriting from one or more mixins.
I've never used Dajax, but I suppose it also uses mixins to provide the basic implementation of the Ajax handling within your views.

Django, polymorphism and N+1 queries problem

I'm writing an app in Django where I'd like to make use of implicit inheritence when using ForeignKeys. As far as I'm concerned the only way to handle this nicely is to use django_polymorphic library (no single table inheritence in Django, WHY OH WHY??).
I'd like to know about the performance implications of this solution. What kind of joins are performed when doing polymorphic queries? Does it have to hit the database multiple times as compared to regular queries (the infamous N+1 queries problem)? The docs warn that "the type of queries that are performed aren't handled efficiently by the modern RDBMs"? However it doesn't really tell what those queries are. Any statistics, experiences would be really helpful.
EDIT:
Is there any way of retrieving a list of objects, each being an instance of its actual class with a constant number of queries ?? I thought this is what the aforementioned library does, however now I got confused and I'm not that certain anymore.
Django-Typed-Models is an alternative to Django-Polymorphic which takes a simple & clean approach to solving the single table inheritance issue. It works off a 'type' attribute which is added to your model. When you save it, the class is persisted into the 'type' attribute. At query time, the attribute is used to set the class of the resulting object.
It does what you expect query-wise (every object returned from a queryset is the downcasted class) without needing special syntax or the scary volume of code associated with Django-Polymorphic. And no extra database queries.
In Django inherited models are internally represented through an OneToOneField. If you are using select_related() in a query Django will follow a one to one relation forwards and backwards to include the referenced table with a join; so you wouldn't need to hit the database twice if you are using select_related.
Ok, I've digged a little bit further and found this nice passage:
https://github.com/bconstantin/django_polymorphic/blob/master/DOCS.rst#performance-considerations
So happily this library does something reasonably sane. That's good to know.

Why does django enforce all model classes to be in models.py?

I have just learned that splitting model classes into different files breaks many of django's built-in functionalities.
I am coming from a java background. There, it is not accepted as a good practice writing very long class files. But django's enforcement of single file for all model classes will probably cause programmer to write very long models.py files. This will make it difficult for programmer to see the organization of the whole domain model.
So why does django enforce single file to contain all domain classes?
I have found a solution proposal to this problem by googling. But I cannot be sure whether this will work properly. Do you suggest this solution?
Single namespace: yes. Single module: no.
Your models have to be importable from namespace appname.models.