Как мне зарегистрировать нового пользователя (пользователя) в фреймворке django rest?

Когда я создаю нового пользователя, соответствующий BaseUser не создается. Сигнал работает правильно, так как я проверил без атрибутов department и user_type как мне прописать BaseUser?

# models.py
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User


class BaseUser(models.Model):
   # TODO: Add a class with static method to return the list of departments(choices)
   # TODO: (REMINDER) To add placeholder that username is rollnumber

USER_TYPES = (
        (0, 'Student'),
        (1, 'Professor'),
        (2, 'Guest'),
)
user = models.OneToOneField(User, primary_key=True,
        related_name='user')
department = models.CharField(max_length=3, default='CSE')
user_type = models.IntegerField(choices=USER_TYPES, default=0)

REQUIRED_FIELDS = [
        'department',
        'email',
        'first_name',
        'user_type'
]

def get_user_type(self):
    return self.USER_TYPES[self.user_type][1]

def __unicode__(self):
    return str(
            dict((
                self.user.user_name,
                self.get_user_type(),
                ))
            )

# serializers.py
from django.contrib.auth.models import User

from rest_framework import serializers

from authentication.models import BaseUser


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (
            'id',
            'username',
            'first_name',
            'email'
        )

class BaseUserSerializer(serializers.ModelSerializer):
    user = UserSerializer()
    user_type = serializers.SerializerMethodField()

    class Meta:
        model = BaseUser
        fields = (
            'user',
            'user_type',
            'department',
        )

    def get_user_type(self, obj):
        return obj.get_user_type()

# views.py
from django.shortcuts import render
from django.contrib.auth.models import User

from rest_framework import viewsets
from rest_framework.decorators import detail_route, list_route

from authentication.models import BaseUser
from authentication.serializers import BaseUserSerializer, UserSerializer


class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

EDIT: я пытался следовать этому подход, но я получил сообщение об ошибке, что у пользователя нет этих атрибутов (т.е. 'Some fields are empty!'

# signals.py
# I have another signal in signals.py and it is working fine.
@receiver(post_save, sender=User)
def create_user_handler(sender, instance, created, **kwargs):
    if created:
        attrs_needed = ['department', 'user_type']
        if all(hasattr(instance, attr) for attr in attrs_needed):
            base_user = BaseUser(
                    user=instance,
                    department=instance.department,
                    user_type=instance.user_type,
            )
            base_user.save()
        else:
            print "Some fields are empty!"
# views
class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @list_route(methods=['post'])
    def create_baseuser(self, request):
        print request.DATA['username']
        user = User.objects.create_user(
                username=request.DATA['username'],
                password=request.DATA['password'],
                email=request.DATA['email'],
                first_name=request.DATA['first_name']
        )

        user.department = request.DATA['department']
        user.user_type = request.DATA['user_type']

        user.save()
        return Response(data='{"detail":"created"')

person Anvesh Arrabochu    schedule 04.06.2015    source источник
comment
Я не вижу никакого кода, который создал бы базового пользователя в случае без DRF... это сейчас происходит для вас? Например, если вы используете команду manage.py для создания пользователя   -  person Alex T    schedule 04.06.2015
comment
Нет, это не так. Не могли бы вы предложить другой способ сделать это   -  person Anvesh Arrabochu    schedule 04.06.2015


Ответы (1)


Если все пользователи будут иметь эти типы, я бы просто предложил расширить пользовательскую модель пользователя для уменьшения головной боли, связанной с сериализатором (особенно если вы хотите иметь возможность просто POST/PUT для /user/, чтобы изменить эти поля и не хотите выполнить упражнение по расширению ваших сериализаторов) https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#specifying-a-custom-user-model

Но если он не работает и в вашем сценарии... может быть, ваш сигнал настроен неправильно? Я не вижу сигнала post_save в исходном коде.

person Alex T    schedule 04.06.2015
comment
Я не думаю, что это сработает, потому что сигнал не будет иметь тип отдела и пользователя, поскольку фактическое определение модели не... - person Alex T; 04.06.2015
comment
Еще одним решением может быть расширение Perform_create ModelSerializer в BaseUserSerializer, чтобы разделить его для создания двух моделей. Но если вы хотите, чтобы все пользователи имели эти поля, можно просто расширить модель пользователя - person Alex T; 04.06.2015
comment
«расширить модель пользователя» — вы имеете в виду расширение AbstractBaseUser? - person Anvesh Arrabochu; 04.06.2015
comment
Да, или AbstractUser (если вы хотите сохранить все поведение по умолчанию + расширить его). Это избавит вас от споров с получением сериализатора для записи в два места (например, если вы хотите обновить как тип, так и адрес электронной почты через вызов REST) - person Alex T; 04.06.2015
comment
Да, я думаю, мне придется унаследовать AbstractBaseUser. Спасибо за вашу помощь! - person Anvesh Arrabochu; 04.06.2015