3👍
Instead of making Total_persons
a separate field, you can drop the field and simply get the number of Person
s belonging to a Country
instance country
with:
country.person_set.count()
Or if you prefer a friendlier name, you can give the Country
foreign key in Person
a related_name
:
class Person(models.Model):
Country = models.ForeignKey(Country, related_name='persons', on_delete=models.CASCADE, null=True)
so that you can get the same count with:
country.persons.count()
Or if you’d still prefer to make Total_persons
a separate field, you can override the Person.save()
method to sync its country when a Person
instance is created (when its pk
is None
), and override the Person.delete()
method to sync when Person
instance is deleted:
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()
3👍
Your model field names should be lower case.
See Coding Style-Model for more information. Also your population and language fields don’t seem to have the right data type??
Another way to achieve what you need is by using model properties.
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()
- [Django]-Django import client
- [Django]-Configuration for setting up nginx with django and nodejs for websocket (wss://)
2👍
You have several ways to have the number of people in countries without a DB field:
With annotations:
qs = Country.objects.annotate(total_people=models.Count('person_set'))
for country in qs:
print(country.total_people)
Else if you really want to have a DB field, you can use post/pre hooks.
There are:
-
@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()
But you’ll have to design things for all use cases when this number could change.