I'm creating a Person Group and Membership as described in Django docs for intermediate model.
class Person(models.Model): name = models.CharField(max_length=128) def __unicode__(self): return self.name class Group(models.Model): name = models.CharField(max_length=128) members = models.ManyToManyField(Person, through='Membership') def __unicode__(self): return self.name class Membership(models.Model): person = models.ForeignKey(Person) group = models.ForeignKey(Group) date_joined = models.DateField() invite_reason = models.CharField(max_length=64)
It is possible to access the Person from a Group object with:
>>>Group.members.name
Does Django creates another query to fetch the Person? Can I access the date_joined
field from a Group object?
The thing that confuses me is that I would expect to get the Person name field with:
>>>Group.members.person.name
What happens if a Person has a field 'name' and also the intermediate model have a field 'name'.
Fields in Django are the data types to store a particular type of data. For example, to store an integer, IntegerField would be used. These fields have in-built validation for a particular data type, that is you can not store “abc” in an IntegerField.
verbose_name is a human-readable name for the field. If the verbose name isn't given, Django will automatically create it using the field's attribute name, converting underscores to spaces. This attribute in general changes the field name in admin interface.
An intermediate model, or in relational database terms, an associative entity, are always needed in a Many-to-Many (M2M) relationship. A relational database requires the implementation of a base relation (or base table) to resolve many-to-many relationships.
Model Meta is basically the inner class of your model class. Model Meta is basically used to change the behavior of your model fields like changing order options,verbose_name, and a lot of other options. It's completely optional to add a Meta class to your model.
The members field in your example is a ManyToManyField, so it's a way to access many people rather than one person. The object that is under the members field is actually a special type of Manager, not a Person:
>>> print my_group.members <django.db.models.fields.related.ManyRelatedManager object at 0x181f7d0>
To understand better what a Manager is, see the documentation.
To access a person's name you would do for example:
>>> for person in my_group.members.all(): >>> print person.name
You cannot access the fields in your Membership model via the Manager in the members field. To access any of the fields in it you would do:
>>> for membership in my_group.membership_set.all(): >>> print membership.date_joined
And so if you had a field called name in your Membership model, you would access it like this:
>>> for membership in my_group.membership_set.all(): >>> print membership.name
A second way to access a Person's name would be:
>>> for membership in my_group.membership_set.all(): >>> print membership.person.name
Note that membership_set
is a default name for the manager pointing towards the membership, but it can be changed by specifying related_name
in the corresponding foreign key. For example if the foreign key from the Membership
to the Group
would be defined like such:
group = models.ForeignKey(Group, related_name="group_members")
Then you would access the manager using group_members
:
>>> for membership in my_group.group_members.all(): >>> print membership.name
Hope that helps a little :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With