Ticket #8018: m2m-example.py

File m2m-example.py, 1.9 KB (added by remo, 7 years ago)

usage examples

Line 
1Ticket #6095 introduced the idea of custom intermediary models. Refractoring the m2m code to always use (generic) intermediary models would have benefits:
2 * a simplier implementation of m2m
3 * appropriate signals are always sent when a relation is created, modified or deleted (eg. #6778)
4 * extending the generic relations (using 'through=') would be easier
5Of course, we must maintain compatibility to the m2m api, which consists (as far as I see it) of the ManyToManyField and the ManyRelatedManager. See the attachment for usage examples.
6
7
8class Survey(models.Model):
9    participants = models.ManyToManyField(User)
10   
11survey = Survey.objects.create()
12# the m2m manager works as usual
13survey.participants.add(User.objects.all())
14survey.participants.remove(User.objects.get(pk=1))
15
16# with the benefit of signals
17# lets assume Survey.participants.Relation is the generic intermediary model
18def notify_of_survey(sender, instance):
19    survey, user = instance # do we need both objects as instance?..
20    user.notify(survey)
21dispatcher.connect(notify_of_survey, signal=post_save, sender=Survey.participants.Relation)
22
23# on to another example
24# the usage of through=
25class Group(models.Model):
26    members = models.ManyToManyField(User, through='Membership')
27
28# as implemented in #6095
29class Membership(models.Model):
30    user = models.ForeignKey(User)
31    group = models.ForeignKey(Group)
32    joined = models.DateField()
33   
34# or even by extending the generic relation
35# which would be abstract when through= is used.
36class Membership(Group.members.Relation):
37    joined = models.DateField()
38   
39group = Group.objects.create()
40user = User.objects.get(pk=1)
41# We should not remove add() etc. from the manager when using an intermediary model (as #6095 does)
42group.members.add(user) # error from Membership.save()
43group.members.add(user, joined=date) # OK
44group.members.add(User.objects.all(), joined=date) # all with the same date
Back to Top