Why I am unable to set Groups despite user having an Id?

I made a custom user model:

from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your models here.
class User(AbstractUser):
    bio = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.first_name+' '+self.last_name

And I try to save it like this:

from app_auth.models import User
from django.contrib.auth.models import Group

from django.db import transaction

class UserService:

    @transaction.atomic
    def create(self,
               username: str,
               email: str,
               first_name: str,
               last_name: str,
               groups: list[Group],
               bio: str | None = None) -> User:

        user = User.objects.create_user(
            username=username,
            first_name=first_name,
            last_name=last_name,
            email=email,
            bio=bio, #TODO: XSS Sanitize
        )

        print("USER ID: "+str(user.id))

        for group in groups:
            print("GROUP ID: "+str(group.pk))

        user.groups.set(groups)

        user.save()
        return user

But I get the following error:

"<User: XXXX XXXXX>" needs to have a value for field "id" before this many-to-many relationship can be used.

The debug print indicates that both user and groups have id:

USER ID: 4
GROUP ID: 4

Do you know why???

There are two common reasons why this happens when dealing with custom user models and Many-to-Many relationships like groups in Django:
1. Direct Assignment Issue
If you are trying to assign the groups directly like user.groups = groups, Django will throw an AttributeError because direct assignment to a Many-to-Many field is prohibited.
Instead, you should use the .set() or .add() method after the user object is created and saved:
python
# Use .set() to assign a list of groups
user.groups.set(groups)

# Or loop through and use .add()
for group in groups:
    user.groups.add(group)
2. Missing AUTH_USER_MODEL in settings.py
Since you created a custom user model class User(AbstractUser):, Django needs to know that it should swap the default user model with your custom one. If you haven't done this, the database relationships won't map correctly.
Go to your settings.py file and add the following line:
python
AUTH_USER_MODEL = 'app_auth.User'  # Replace 'app_auth' with your actual app name
Вернуться на верх