1

I want to be able to attach a user to a group upon creation.

Here is the result of select * from auth_group:

image screenshoot

Here is the my serializer.py file:

from rest_framework import serializers

from .models import User


class UserSerializer(serializers.ModelSerializer):

class Meta(object):
    model = User
    fields = ('id', 'email', 'first_name', 'last_name', 'phone', 'address', 'is_active', 'is_staff',
              'is_superuser', 'date_joined', 'password',)
    extra_kwargs = {'password': {'write_only': True}}

Here is my model.py file:

from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import PermissionsMixin, UserManager, Group
from django.db import models, transaction

# Create your models here.
from django.utils import timezone


class UserManager(BaseUserManager):

    def _create_user(self, email, password, **extra_fields):
    """
    Creates and saves a User with the given email,and password.
    """
    if not email:
        raise ValueError('User must have an email address')
    email = self.normalize_email(email)
    if not extra_fields["group_id"]:
        raise ValueError('User must have group id')
    try:
        with transaction.atomic():
            user = self.model(email=email, **extra_fields)
            group = Group.objects.get(extra_fields["group_id"])
            group.user_set.add(user)
            user.set_password(password)
            user.save(using=self._db)
            return user
    except:
        raise

def create_user(self, email, password=None, **extra_fields):
    extra_fields.setdefault('is_staff', False)
    extra_fields.setdefault('is_superuser', False)
    return self._create_user(email, password, **extra_fields)

def create_superuser(self, email, password, **extra_fields):
    extra_fields.setdefault('is_staff', True)
    extra_fields.setdefault('is_superuser', True)

    return self._create_user(email, password=password, **extra_fields)


class User(AbstractBaseUser, PermissionsMixin):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.

"""
email = models.EmailField(max_length=40, unique=True)
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
phone = models.CharField(max_length=20, blank=True)
address = models.CharField(max_length=30, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)

objects = UserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'phone']

def get_full_name(self):
    """" Used to display user's full name """
    return "{}, {}".format(self.first_name, self.last_name)

def __srt__(self):
    return self.email

def save(self, *args, **kwargs):
    super(User, self).save(*args, **kwargs)
    return self

And finally, here is my view.py:

class CreateUserAPIView(APIView):
# Allow any user (authenticated or not) to access this url
permission_classes = (AllowAny,)

def post(self, request):
    user = request.data
    serializer = UserSerializer(data=user)
    serializer.is_valid(raise_exception=True)
    serializer.save()
    return Response({"user": serializer.data, "status": status.HTTP_200_OK})

I want for this request:

{
"email": "myemail@gmail.com",
"first_name": "myfirst_name",
"last_name": "mylast_name",
"phone": "000556660",
"address": "myaddress",
"password": "mypassword",
"group_id": 5
}

To get this response:

{
"status": 200,
user: {
"email": "myemail@gmail.com",
"first_name": "myfirst_name",
"last_name": "mylast_name",
"phone": "000556660",
"address": "myaddress",
"password": "mypassword",
"groups": [5]
}
}

I have followed this link Adding a user to a group in django but it's not helping me.

Thanks, any help would be appreciated.

arulmr
  • 8,620
  • 9
  • 54
  • 69
Mwimo clement
  • 11
  • 1
  • 3
  • 2
    In which way is your code not working? What's the behavior when a request is submitted? Any output or error message? – blhsing Jun 26 '18 at 20:43

1 Answers1

5

Try this :

class UserSerializers(serializers.ModelSerializer):
# groups = GroupSerializer(many=True)

class Meta:
    model = User
    fields = ('id', 'email', 'first_name', 'last_name', 'phone', 'address', 'is_active', 'is_staff',
          'is_superuser', 'date_joined', 'password', 'groups')

def create(self, validated_data):
    groups_data = validated_data.pop('groups')
    user = User.objects.create(**validated_data)
    for group_data in groups_data:
        # Group.objects.create(user=user, **group_data)
        user.groups.add(group_data)
    return user

Edit: Because User and Group are in many-to-many relations so you can directly add the group field in the users serializers. For more details follow django.contrib.auth.models package and User inherits AbstactUser and AbstractUser inherits PermissionsMixin which has groups as many to many field.

Bishwa Karki
  • 359
  • 4
  • 20
  • Code-only answers are discouraged. Please click on [edit] and add some words summarising how your code addresses the question. Thanks – Nick Jan 08 '19 at 03:22
  • Could you please explain how this helps to solve OP's problem? Because he hasn't specified one, so it's a mystery to me how you've managed to come up with a solution. – chb Jan 08 '19 at 03:22
  • So as of my edit, User and Groups are many-to-many fields and now `groups` attribute becomes available to `User` model. – Bishwa Karki Jan 08 '19 at 05:59