Django: select_related to a table vs table's field - django

I have 2 models
class A(models.Model):
val = models.IntegerField()
class B(models.Model):
val2 = models.IntegerField()
a = models.ForeignKey(A)
class C(models.Model):
b = models.ForeignKey(B)
val3 = models.IntegerField()
How is the query -
C.objects.select_related('B').all()
better than -
C.objects.select_related('B__val2').all()
And if not how query one can be optimised?

Try to filter model you need, by lowcase filter of the child models
B.objects.filter(c__isnull=False)
read more here lookups-that-span-relationships

Related

Is it possible to prefetch model with one query in this case?

Is it possible to prefetch Models B to Model A with one query or with minimal queries. I'm confused. Thanks.
from django.db import models
class ModelA(models.Model):
pass
class ModelB(models.Model):
pass
class ModelC(models.Model):
model_a = models.ForeignKey(ModelA, related_name="models_a", on_delete=models.CASCADE)
models_b = models.ManyToMany(ModelB, through="ModelD")
class ModelD(models.Model):
model_c = models.ForeignKey(ModelC, on_delete=models.CASCADE)
model_b = models.ForeignKey(ModelB, on_delete=models.CASCADE)
I'm do something like that, and it is work. But seems a bit ugly.
models_a_list = ModelsA.objects.all()
model_d_qs = ModelD.objects.select_related("model_c", "model_b")
model_d_map = defaultdict(list)
for d_item in model_d_qs:
model_d_map[d_item.model_c.model_a.id].append(d_item.model_b)
for a_item in models_a_list:
settatr(a_item, "model_b_set", model_d_map.get(a_item.id))
return models_a_list

Django models filter by one to one model field

Imagine I have those two models:
class A(models.Model):
name = models.CharField(max_length=150)
class B(models.Model):
a = models.OneToOneField(
to=A, on_delete=models.CASCADE, null=False
)
location = models.CharField(max_length=100)
And I want a queryset of B model to be filtered by the a.name and location,
like this:
select * from B join A
on B.a.pk = A.pk
where A.name="name" and B.location="location";
I tried this but it gives an error:
query=B.objects.filter(a.name=name)
Read the documentation carefully. U can access related fields with double underscore. So in your case dat will be:
query=B.objects.filter(a__name='name', location='location')

How to get data from two tables with DjangoORM?

I have two tables in the database:
class CustomerEquipment(models.Model):
serial_number = models.CharField(max_length=255)
state_timestamp = models.DateTimeField()
state_type = models.IntegerField()
class Meta:
managed = False
db_table = 'customer_equipment'
class LogCustomerEquipment(models.Model):
state = models.IntegerField()
state_timestamp = models.DateTimeField()
serial_number = models.CharField(max_length=255)
class Meta:
managed = False
db_table = 'log_customer_equipment'
I execute two database queries:
customer_equipment_list = CustomerEquipment.objects.using('portal').filter(
Q(state_type=10) & Q(state_timestamp__icontains='2020-02-27')
)
log_customer_equipment_list = LogCustomerEquipment.objects.using('portal').filter(
Q(state=2) & Q(state_timestamp__icontains='2020-02-27')
)
I need to get serial_number which are in both tables.
How to do it? How can I optimize queries? The same serial_number can be in both tables. Need to choose those that intersect.
You can try this:
set(CustomerEquipment.objects.values_list('serial_number ', flat=True)) & set(LogCustomerEquipment.objects.values_list('serial_number ', flat=True))
or maybe you should refactor models from the relation.
For example, using ForeignKey or ManyToManyField.

prefetch_related with nested m2m

Given the following models I would like to improve the performance of the filter to avoid unnecessary calls to DB.
class A(models.Model):
name = models.CharField()
b = ManyToManyField(B)
class B(models.Model):
c = ManyToManyField(C)
class C(models.Model):
d = ManyToManyField(D)
class D(models.Model):
foo = models.TextField()
How could I achieve this with prefetch_related?
''.join(A.objects.filter(b__c__d=self.d).prefetch_related('??').values_list('name', flat=True))
It works in a similar fashion to your filter (b__c__d). Just prefetch:
''.join(A.objects.filter(b__c__d=self.d).prefetch_related('b__c__d').values_list('name', flat=True))

Django model for same structured databases

I have different data databases of same database schema (also in 1 database: different tables with same structure/schema) and I want use those databases in all my other apps as data backend.
For example,
database name: database1
class tableA(models.Model):
a = models.CharField()
b = models.CharField()
class Meta:
db_table = 'tableA'
class tableB(models.Model):
c = models.CharField()
d = models.CharField()
class Meta:
db_table = 'tableB'
class tableC(models.Model):
c = models.CharField()
d = models.CharField()
class Meta:
db_table = 'tableC'
database name: database2
class tableA(models.Model):
a = models.CharField()
b = models.CharField()
class Meta:
db_table = 'tableA'
class tableB(models.Model):
c = models.CharField()
d = models.CharField()
class Meta:
db_table = 'tableB'
class tableC(models.Model):
c = models.CharField()
d = models.CharField()
class Meta:
db_table = 'tableC'
Here, you can see database1 and database2 is having same schema. Also in both databases, tables: tableB and tableC having same schema. In short there is seperate database created for each region with same structure instead of 1 big database for all regions. In 1 database I have around 15 tables and out of 15, 12 tables having same schema in which daily data is stored.
Can anyone please tell me how should I design this in django? Should I create 1 app with multiple model files (1 for each database) and direct it to different databases with router? How? Or create different app for each database? You can see in both cases there is a lot of code redudency as all model files having same structure.