Search code examples
pythondjangodatabasemany-to-manyuser-accounts

Django many-to-many relations


I'm trying to create a web app in which users can participate in some groups (every user can be part of multiple groups), and I want to be able to make both queries like

group.users_set()

and

user.groups_set()

I want to see all groups a user is participating to in the admin page of every user and vice versa. My last attempt was this:

class CustomUser(AbstractUser):
    groups = models.ManyToManyField('Group', through='Participation')

class Group(models.Model):
    group_name = models.CharField(max_length=200)    
    group_password = models.CharField(max_length=200)
    customusers = models.ManyToManyField('CustomUser', through='Participation')

class Participation(models.Model):
    customuser = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE) 

but I get

django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:

ERRORS:
<class 'userreg.admin.CustomUserAdmin'>: (admin.E013) The value of 'fieldsets[2][1]["fields"]' cannot include the ManyToManyField 'groups', because that field manually specifies a relationship model.

Before, with just

users = models.ManyToManyField(CustomUser)

in the Group class and without the Participation class, I was able to get half of my goal, seeing the list of logged users in the admin page. What am I doing wrong?


Solution

  • The answer provided by @Willem Van Onsem was very useful, but I solved my problem doing this in models.py

    class CustomUser(AbstractUser):
        groups = models.ManyToManyField('Group')
    
    class Group(models.Model):
        name = models.CharField(max_length=200)
        password = models.CharField(max_length=200)
        users = models.ManyToManyField(CustomUsers)
    

    and this in admin.py:

    from django.contrib import admin
    from .models import Group, CustomUser
    from django.contrib.auth.admin import UserAdmin
    
    class GroupAdmin(admin.ModelAdmin):
        fieldsets = [
            (None,               {'fields': ['group_name', 'group_password']}),
            ('Users', {'fields': ['users']}),
        ]
    
    class CustomUserAdmin(UserAdmin):
        fieldsets = [
            (None,               {'fields': ['username', 'password']}),
            ('Groups', {'fields': ['groups']}),
        ]
        
    
    admin.site.register(CustomUser, CustomUserAdmin)
    
    admin.site.register(Group, GroupAdmin)