Как "заставить" разделять экземпляры модели между объектами в django при использовании prefetch_related()?
Мой вопрос таков:
- Как "заставить" экземпляры модели быть общими?
- В приведенном ниже примере вывода строка 3 и строка 5 имеют
Person(2)
с разными идентификаторами экземпляров объектов.- Это означает, что существует 2 экземпляра модели одного и того же объекта, на которые ссылаются из двух разных мест .
- Я бы хотел, чтобы они указывали на точно такой же экземпляр объекта.
- Таким образом, будет только 1 экземпляр модели каждого объекта, на который будут ссылаться из нескольких разных мест .
- Кроме того, когда поле обновляется (например,
p2.name = 'p_two'
), я хотел бы, чтобы оно было "видно" либо при доступе кPerson2
через любой изGroup12
илиGroup23
, без необходимости сохранять и получать данные снова. На данном этапе нет необходимости сохранять состояние модели в базе данных.
В документации сказано:
Пример: models.py
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return f'<{hex(id(self))} P({self.pk}) {self.name}>'
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(to=Person, through='Membership')
def __str__(self):
return f'<{hex(id(self))} G({self.pk}) {self.name}>'
class Membership(models.Model):
person = models.ForeignKey(to=Person, on_delete=models.CASCADE)
group = models.ForeignKey(to=Group, on_delete=models.CASCADE)
member_nickname = models.CharField(max_length=128)
def __str__(self):
return f'<{hex(id(self))} M({self.pk}) of {self.person} in {self.group}>'
Пример tests.py
class MyTests(TestCase):
def test_object_ids(self):
p1 = Person.objects.create(name='person1')
p2 = Person.objects.create(name='person2')
p3 = Person.objects.create(name='person3')
g12 = Group.objects.create(name='group1')
g23 = Group.objects.create(name='group2')
g31 = Group.objects.create(name='group3')
Membership.objects.create(person=p1, group=g12, member_nickname='p1-in-g12')
Membership.objects.create(person=p2, group=g12, member_nickname='p2-in-g12')
Membership.objects.create(person=p2, group=g23, member_nickname='p2-in-g23')
Membership.objects.create(person=p3, group=g23, member_nickname='p3-in-g23')
Membership.objects.create(person=p3, group=g31, member_nickname='p3-in-g31')
Membership.objects.create(person=p1, group=g31, member_nickname='p1-in-g31')
gs = Group.objects.all().prefetch_related()
for g in gs:
print(g)
for m in g.membership_set.all():
print('\t', m)
Пример вывода:
Line 1: <0x2960a4b35b0 G(1) group12>
Line 2: <0x2960a5cc310 M(1) of <0x2960a5cc730 P(1) person1> in <0x2960a4b35b0 G(1) group12>>
Line 3: <0x2960a5ccb80 M(2) of <0x2960a5cc9a0 P(2) person2> in <0x2960a4b35b0 G(1) group12>>
Line 4: <0x2960a4af1c0 G(2) group23>
Line 5: <0x2960a5cc8b0 M(3) of <0x2960a5ccc40 P(2) person2> in <0x2960a4af1c0 G(2) group23>>
Line 6: <0x2960a5cc2e0 M(4) of <0x2960a5cc100 P(3) person3> in <0x2960a4af1c0 G(2) group23>>
Line 7: <0x2960a4af3a0 G(3) group31>
Line 8: <0x2960a5cc4c0 M(5) of <0x2960a5cc730 P(3) person3> in <0x2960a4af3a0 G(3) group31>>
Line 9: <0x2960a5c27f0 M(6) of <0x2960a5c25b0 P(1) person1> in <0x2960a4af3a0 G(3) group31>>