Django: meta class order ignoring NULL - python

I need to sort queryset using Django model's meta class.
I've defined it like this:
class MyModel(models.Model):
order = models.IntegerField(blank=True, null=True)
class Meta:
ordering = ['order']
Some records have null as its "order" value.
If I get queryset, then the records that has null as order value are placed at beginning of result.
I just want to place such records at the end of queryset.
I've checked some articles for this purpose.
django order by isnull value?
Django : Order by position ignoring NULL
But I need it to be done using Django model's Meta class.
Is there any idea to do it via Meta class?
Regards
Philip

Related

How to allow boolean True on just one model in table in Django?

I've got a model where I would like there to be able to have one set as the 'app default'.
In this model I added a field named is_app_default in order to help accommodate this.
class TreeLevel(models.Model):
id = models.BigAutoField(primary_key=True)
short_description = models.CharField(max_length=200)
long_description = models.TextField()
is_app_default = models.BooleanField(default=False)
class Meta:
verbose_name = "Tree Level"
verbose_name_plural = "Tree Levels"
class Layer(models.Model):
id = models.BigAutoField(primary_key=True)
tree_levels = models.ManyToManyField(TreeLevel)
description = models.TextField()
class Meta:
verbose_name = "Layer"
verbose_name_plural = "Layers"
The Layer model links to TreeLevel with an m2m. Ultimately I would like the is_app_default TreeLevel automatically added to every Layer m2m relationship - which is why there can only be one TreeLevel with is_app_default set as True.
My potential solution(s):
Users with admin may be creating new TreeLevel objects - so I need to make sure they aren't setting that Boolean in any new models. I think I can override the save() method on TreeLevel to check the DB to see if another with that boolean as True exists - if so? Don't save the 'new' one and return an error. But I think this hits the database - causing unnecessary queries potentially?
Then additionally, I would also need to override the save() method on Layer and add the 'default' TreeLevel to that many2many at that time.
Is there a good way to 'automatically' handle this with these relationships?
My ultimate goal:
Have a default TreeLevel that is automatically added to every Layer many to many relationship whenever a Layer is created.
Questions:
Would my proposed solution work?
I've tried looking into Djangos Unique Constraints, but I think those are more on a row level, as opposed to a Table level.

Django queryset has no attribute when using select related

I'm trying to using select_related to queryset, and it returns queryset has no attribute when using select related. I made two models, and one model has foreignkey column, it is 1:1.
models
class User(models.Model):
name = Charfield()
class Item(models.Model):
user = models.ForegnKey(User, on_delete=models.CASCADE, related_name='user_item_set', null=True)
When I try this queryset, it says queryset does not have select related.
users = User.objects.get(id=pk).select_related('user_item_set')
Looks like you misunderstood the usage of select_related().
Returns a QuerySet that will “follow” foreign-key relationships, selecting additional related-object data when it executes its query.
It can be used on Item model (the model which defines the ForegnKey field) and not User model.
What you need to use is prefetch_related(). Something like this:
users = User.objects.get(id=pk).prefetch_related('item_set')

Django models: set default IntegerField to number of instances

I would like to set the "order" IntegerField of my Achievement model to the current count of objects in Achievement. The order field is used to order achievements, and users can change it. For now I have 1 as default.
class Achievement(models.Model):
title = models.CharField(max_length=50, blank=True)
description = models.TextField()
order = models.IntegerField(default=1) #Get the number of achievement objects
class Meta:
db_table = 'achievement'
ordering = ['order', 'id']
For example, if I already have one achievement in my database with whatever order the next one should get order=2 by default.
As far as I understood, you want to have a default value of 1 to the order integer field and increment it with each entry of Achievment (same functionality as the id), but also allow users change it.
For this purpose you can use Django's AutoField:
An IntegerField that automatically increments according to available IDs. You usually won’t need to use this directly; a primary key field will automatically be added to your model if you don’t specify otherwise.
Like this:
class Achievement(models.Model):
...
order = models.AutoField(default=1, primary_key=False)
# Also specify that this autofield is *not* a ^ primary key
class Meta:
ordering = ['order', 'id']

Fast filter on related fields in django

I have 2 models in my django project.
ModelA(models.Model):
id = models.AutoField(primary_key=True)
field1 = ...
~
fieldN = ...
ModelB(models.Model):
id = models.AutoField(primary_key=True)
a = models.ForeignKey(A, on_delete=models.CASCADE)
field1 = ...
~
fieldN = ...
Here I have one-to-mane relation A->B. Table A has around 30 different fields and 10.000+ rows and table B has around 15 and 10.000.000+ rows. I need to filter firstly by the several ModelA fields and then for each of the filtered ModelA row/object get related ModelB objects and filter them by several fields. After that I need to serialize them in JSON where all ModelB packed in one field as array.
Is it possible to perform this around the 1-3 second? If yes, what is the best approach?
I use PostgreSQL.
EDIT:
Now I am doing it like chain .filter() on simple ModelA fields and then iterate over resulted QuerySet and get set of ModelB for each ModelA instance,but i suspect, that the second part of this solution will slow down whole process, so I suppose there is a better way to do it.
It may be faster to do a query like this:
model_a_queryset = ModelA.objects.filter(field=whatever)
model_b_queryset = ModelB.objects.filter(a__in=model_a_queryset)
Because Django does lazy queryset evaulation, this will only result in one hit to the database.
As an aside, there is no need to define id = Autofield fields on your models. Django includes them by default.

Design an observation pattern in Django Rest Framework

I want to implement something like the pattern which introduced in this answer. For example I have four models like this:
class Protperty(models.Model):
property_type = models.CharField(choices=TYPE_CHOICES, default='float', max_length=100)
property_name = models.CharField(max_length=100)
class FloatProperty(models.Model):
property_id = models.ForeignKey(Property, related_name='value')
value = models.FloatField(default=0.0)
class IntProperty(models.Model):
property_id = models.ForeignKey(Property, related_name='value')
value = models.IntField(default=0)
class StringProperty(models.Model):
property_id = models.ForeignKey(Property, related_name='value')
value = models.CharField(max_lenght=100, blank=True, default='')
After defining these classes, I do not know how I must implement serializer or view classes. For example for writing serializer I want to put a field value, which must be set depend of type of object currently is serialized or deserialilzed(property_type defines it).
I am new to django and rest framework too, please give me some suggestions for implementing such models and serializers.
Edit:
In general I want to construct some models that using them I able to store run time defining property with different values and able to query them further. For example I have a store and it has different goods which each one has specific property and I want to query them using a specific property.

Categories