'Django customization of loading a foreign key
Assume I have three related classes such as:
class A:
...
class B:
...
a = models.ForeignKey(A, ...)
class C:
...
b = models.ForeignKey(B, ...)
I want to customize accessing b on C object to load a immediately. It means whenever I called c.b a select_related query call a too. There are also other scenario which I need to be able to use prefetch_related.
I am using django 3.1.1
Solution 1:[1]
You can do this if you want to reuse some select_related() with foreign keys :
from django.db import models
from django.db.models.fields.related_descriptors import ForwardManyToOneDescriptor
class FullBForwardManyToOneDescriptor(ForwardManyToOneDescriptor):
def get_object(self, instance):
qs = self.get_queryset(instance=instance).select_related("a")
# Assuming the database enforces foreign keys, this won't fail.
return qs.get(self.field.get_reverse_related_filter(instance))
class FullBForeignKey(models.ForeignKey):
forward_related_accessor_class = FullBForwardManyToOneDescriptor
class C:
...
b = FullBForeignKey(B, ...)
class D:
...
b = FullBForeignKey(B, ...)
class E:
...
b = FullBForeignKey(B, ...)
You can create other classes inheriting ForwardManyToOneDescriptor and ForeignKey for each of your use cases, if you have many use cases for B foreign key.
class F:
...
b = SomeExtraBForeignKey(B, ...)
class G:
...
b = SomeExtraBForeignKey(B, ...)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
