Как создать нового пользователя с картой отдыха django и пользовательской пользовательской моделью

У меня есть пользовательская модель, и я использую django-rest-framework для создания API

models.py:

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        unique=True,
        max_length=254,
    )
    first_name = models.CharField(max_length=15)
    last_name = models.CharField(max_length=15)
    mobile = models.IntegerField(unique=True)
    date_joined = models.DateTimeField(default=timezone.now)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

serializers.py:

class UserSerializer(serializers.ModelSerializer):
    password1 = serializers.CharField(write_only=True)
    password2 = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'mobile', 'password1', 'password2')

views.py:

@api_view(['POST'])
@permission_classes((AllowAny,))
def create_user(request):
    serialized = UserSerializer(data=request.data)
    if serialized.is_valid():
        User.objects.create_user(
            serialized.save()
        )
        return Response(serialized.data, status=status.HTTP_201_CREATED)
    else:
        return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)

Однако, когда я пытаюсь создать нового пользователя, я получаю эту ошибку:

Получаем TypeError при вызове User.objects.create(). Это может быть связано с тем, что у вас есть поля для записи в классе сериализатора, который не является допустимым аргументом для User.objects.create(). Возможно, вам понадобится сделать поле только для чтения или переопределить метод UserSerializer.create(), чтобы правильно его обрабатывать.

Это может быть потому, что в пользовательской модели нет полей password1 или password2. Но так, как я могу создать API для создания нового пользователя с помощью django-rest-framework?

Ответ 1

Я думаю, что одного поля пароля достаточно. Если вы хотите, чтобы пользователь дважды проверял ввод пароля, сделайте это во внешнем интерфейсе. Вы можете переопределить метод create из сериализатора следующим образом.

from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'mobile', 'password')

    def create(self, validated_data):
        user = super(UserSerializer, self).create(validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user

views.py

from rest_framework import generics
from rest_framework.permissions import AllowAny
from .models import User
from .serializers import UserSerializer

class UserCreateAPIView(generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (AllowAny,)

Ответ 2

В model.py:

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

STATUS_CHOICES = (
    ('inprogress', 'In Progress'),
    ('close', 'Close'),
    ('cancelled', 'Cancelled'),
)


class Task(models.Model):
    title = models.CharField(max_length=50)
    content = models.TextField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='inprogress')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

В views.py из rest_framework импортируйте дженерики

from tasks.models import Task
from tasks.serializers import TaskSerializer


class TaskList(generics.ListCreateAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

    def create(self, request, *args, **kwargs):
    # your custom implementation goes here
    return Response(response)


class TaskDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer