Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Django中添加所有外键关系?_Python_Django_Python 3.x_Django Models - Fatal编程技术网

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()