-
-
Save jacobian/827937 to your computer and use it in GitHub Desktop.
from django.db import models | |
class Person(models.Model): | |
name = models.CharField(max_length=200) | |
groups = models.ManyToManyField('Group', through='GroupMember', related_name='people') | |
class Meta: | |
ordering = ['name'] | |
def __unicode__(self): | |
return self.name | |
class Group(models.Model): | |
name = models.CharField(max_length=200) | |
class Meta: | |
ordering = ['name'] | |
def __unicode__(self): | |
return self.name | |
class GroupMember(models.Model): | |
person = models.ForeignKey(Person, related_name='membership') | |
group = models.ForeignKey(Group, related_name='membership') | |
type = models.CharField(max_length=100) | |
def __unicode__(self): | |
return "%s is in group %s (as %s)" % (self.person, self.group, self.type) |
from django.test import TestCase | |
from .models import Person, Group, GroupMember | |
class M2MThroughTest(TestCase): | |
def setUp(self): | |
# Create three people: | |
self.joe = Person.objects.create(name='Joe') | |
self.jim = Person.objects.create(name='Jim') | |
self.bob = Person.objects.create(name='Bob') | |
# And three groups: | |
self.jocks = Group.objects.create(name='Jocks') | |
self.nerds = Group.objects.create(name='Nerds') | |
self.skaters = Group.objects.create(name='Skaters') | |
# Every person is a member of every group, but | |
# Joe admins jocks, Jim admins nerds, and Bob admins skaters. | |
GroupMember.objects.create(person=self.joe, group=self.jocks, type="admin") | |
GroupMember.objects.create(person=self.jim, group=self.jocks, type="member") | |
GroupMember.objects.create(person=self.bob, group=self.jocks, type="member") | |
GroupMember.objects.create(person=self.joe, group=self.nerds, type="member") | |
GroupMember.objects.create(person=self.jim, group=self.nerds, type="admin") | |
GroupMember.objects.create(person=self.bob, group=self.nerds, type="member") | |
GroupMember.objects.create(person=self.joe, group=self.skaters, type="member") | |
GroupMember.objects.create(person=self.jim, group=self.skaters, type="member") | |
GroupMember.objects.create(person=self.bob, group=self.skaters, type="admin") | |
def test_unfiltered_membership(self): | |
# Which groups is Jim in? | |
jims_groups = Group.objects.filter(people=self.jim) | |
self.assertEqual(list(jims_groups), [self.jocks, self.nerds, self.skaters]) | |
def test_admin_groups(self): | |
# But which groups does Jim admin? | |
jim_admins = Group.objects.filter(people=self.jim, membership__type='admin') | |
self.assertEqual(list(jim_admins), [self.nerds]) | |
def test_member_groups(self): | |
# And which groups is Bob just a member of? | |
bob_membership = Group.objects.filter(people=self.bob, membership__type='member') | |
self.assertEqual(list(bob_membership), [self.jocks, self.nerds]) |
Also, I think this is actually a bug...down to PR django if I'm not just being dumb. Check out that stackoverflow if you don't mind and let me know.
how to query all Groups a person involved in ?
Also how to query All persons in a group ?
@osjayaprakash try this
how to query all Groups a person involved in ?
R: having the person, use person.groups as the field is declared in model.
Also how to query All persons in a group ?
R: having the group, use group.people as the related_name define in ManyToMany field.
Thanks for example!
gives error. this code lacks more info.
Very helpful, thanks for the example.
Nine years later, still helpful. Thank you for this.
Nice example! 👏🏻
Thanks
Thanks, I was stuck!
Nice Example~~
thank you for sharing
Really helped me a lot. Thanks for sharing.
Thanks for sharing. Very helpful
Thanks for this...helped me easily write a fix with some weird foreign key reference issues.
See: http://stackoverflow.com/questions/24127467/django-1-6-python-2-7-manytomany-not-mapping-references-to-joined-tables