Python 如何在Django中添加所有外键关系?
我有这两种型号:Python 如何在Django中添加所有外键关系?,python,django,python-3.x,django-models,Python,Django,Python 3.x,Django Models,我有这两种型号: class Country(models.Model): Name = models.CharField(max_length=100) Population = models.CharField(max_length=100) Language = models.IntegerField() Total_persons= models.IntegerField() class Person(models.Model): Country
class Country(models.Model):
Name = models.CharField(max_length=100)
Population = models.CharField(max_length=100)
Language = models.IntegerField()
Total_persons= models.IntegerField()
class Person(models.Model):
Country = models.ForeignKey(Country, on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=100)
contact = models.IntegerField()
在国家
我有美国、加拿大、墨西哥、西班牙、法国。。。。。。
在Person
中,我有1000多人
如何使
总人数
随着该国总人数
的增加而增加。不必将总人数
设为单独的字段,您可以删除该字段,只需通过以下方式获取属于国家的人员
人数:
country.person_set.count()
或者,如果您喜欢更友好的名字,您可以在人名中输入国家
外键相关名称
:
class Person(models.Model):
Country = models.ForeignKey(Country, related_name='persons', on_delete=models.CASCADE, null=True)
因此,您可以通过以下方式获得相同的计数:
country.persons.count()
或者,如果您仍然希望将Total_persons
作为一个单独的字段,则可以重写Person.save()
方法,以便在创建Person
实例时(当其pk
为None
时)同步其国家/地区,并重写Person.delete()
删除个人
实例时的同步方法:
class Person(models.Model):
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if not self.pk:
self.Country.Total_persons = self.Country.person_set.count()
self.Country.save()
def delete(self):
country = self.Country
super().delete()
country.Total_persons = country.person_set.count()
country.save()
您的模型字段名称应为小写。
有关更多信息,请参阅。此外,您的人口和语言字段似乎没有正确的数据类型
实现所需功能的另一种方法是使用模型属性
class Country(models.Model):
name = models.CharField(max_length=100)
population = models.CharField(max_length=100)
language = models.IntegerField()
@property
def total_people(self):
return self.people.count()
class Person(models.Model):
Country = models.ForeignKey(Country, on_delete=models.CASCADE, null=True,
related_name='people')
name = models.CharField(max_length=100)
contact = models.IntegerField()
有几种方法可以计算没有DB字段的国家/地区的人口数量:
与:
否则,如果您真的想要一个DB字段,您可以使用post/pre挂钩。
有:
-
-
但是,当这个数字可能发生变化时,您必须为所有用例设计一些东西。您应该使用.count()
而不是len(self.countries)
,否则queryset将被计算为count,其中只有a DB请求才能给出要求。@Zulu我更改了答案以反映这一点。如果你能取消否决票就好了,因为我的回答是正确的。
qs = Country.objects.annotate(total_people=models.Count('person_set'))
for country in qs:
print(country.total_people)
@receiver(post_save, sender=Person)
def increment_total_people(sender, instance, created, **kwargs):
instance.Country.Total_persons += 1
instance.Country.save()
@receiver(post_delete, sender=Person)
def decrement_total_people(sender, instance, **kwargs):
instance.Country.Total_persons -= 1
instance.Country.save()