Issue
How to retrieve value from a method in Django's model I have two models Model1 and Model2, Model2 is related to Model1. The method is located in Model2. The method name is get_organization_name
class Model1(models.Model):
code = models.CharField(max_length=5)
random_id = models.IntegerField(primary_key=True)
random_type = models.CharField(max_length=5)
random_code = models.CharField(max_length=10)
random_name = models.CharField(max_length=200)
class Model2(models.Model):
id = models.AutoField(primary_key=True)
claim_id = models.PositiveIntegerField()
random = models.OneToOneField('Model1', on_delete=models.DO_NOTHING,
db_column='random_id', related_name='polis_journal')
random_type = models.CharField(max_length=255)
organization_id = models.PositiveIntegerField()
def get_organization_name(self):
return polis_organizations.get(self.organization_id, None)
I have tried following:
queryset = Model1.objects.all()
queryset = queryset.annotate(organization_name=F('polis_journal__get_organization_name')
Solution
You don't, or at least not without applying "tricks" to "translate" the method into a database expression.
In this specific case, we probably have a dictionary lookup, so we can do this with:
from django.db.models import Case, Value, When
queryset = Model1.objects.annotate(
organization_name=Case(
*[
When(polis_journal__organization_id=k, then=Value(v))
for k, v in polis_organizations.items()
],
default=Value(None)
)
)
but not only is this ugly, and will this result in a large expression, it will perform dictionary lookups in linear time.
Usually one just stores the name of the organization in a model:
class Organization(models.Model):
name = models.CharField(max_length=128, unique=True)
class Model2(models.Model):
# …
organization = models.ForeignKey(Organization, on_delete=models.PROTECT)
and then we can thus work with:
Model1.objects.annotate(organization_name=F('polis_journal__organization__name'))
Answered By - willeM_ Van Onsem
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.