Django rest框架未更新扩展用户模型

Django rest框架未更新扩展用户模型,django,django-rest-framework,django-authentication,django-1.8,Django,Django Rest Framework,Django Authentication,Django 1.8,我在Django中扩展了用户模型,它是客户类型的。我正在使用django rest框架(DRF)。因此,在阅读DRF中的文档时,我了解了如何在嵌套模型中编写文档,因此我在serializer中重写了create和update方法,创建工作正常,但更新并不像它所说的那样: HTTP 400 Bad Request Allow: GET, PUT, PATCH, DELETE, OPTIONS Content-Type: application/json Vary: Accept { "u

我在Django中扩展了用户模型,它是客户类型的。我正在使用django rest框架(DRF)。因此,在阅读DRF中的文档时,我了解了如何在嵌套模型中编写文档,因此我在serializer中重写了create和update方法,创建工作正常,但更新并不像它所说的那样:

HTTP 400 Bad Request
Allow: GET, PUT, PATCH, DELETE, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "user": {
        "username": [
            "A user with that username already exists."
        ]
    }
}
这是我的客户模型:

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


class Customer(models.Model):
    user = models.OneToOneField(User, related_name="customer", on_delete=models.CASCADE)
    date_of_birth = models.DateField(max_length=8)

    def __unicode__(self):
        return u'%s' % self.user.username
我的用户序列化程序:

from django.contrib.auth.models import User

from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model

from rest_framework import serializers

from customers.models import Customer
from api.serializers import UserSerializer


class CustomerSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Customer
        fields = ('url', 'date_of_birth', 'user')
        depth = 1

    def create(self, validated_data):
        print "coming inside create"
        user_data = validated_data.pop("user")
        user = User.objects.create(**user_data)
        customer = Customer.objects.create(user=user, **validated_data)
        return customer

    def update(self, instance, validated_data):
        print "coming inside update"
        user_data = validated_data.pop("user")
        username = user_data.pop('username')
        user = get_user_model().objects.get_or_create(username=username)[0]
        user.email = user_data.get('email', user.email)
        user.save()

        instance.user = user
        instance.date_of_birth = validated_data.get('date_of_birth', instance.date_of_birth)
        instance.save()



        return instance
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
        extra_kwargs = {
            'username': {'validators': []},
        }
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
        extra_kwargs = {
            'username': {'validators': []},
        }
和我的扩展客户模型序列化程序:

from django.contrib.auth.models import User

from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model

from rest_framework import serializers

from customers.models import Customer
from api.serializers import UserSerializer


class CustomerSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Customer
        fields = ('url', 'date_of_birth', 'user')
        depth = 1

    def create(self, validated_data):
        print "coming inside create"
        user_data = validated_data.pop("user")
        user = User.objects.create(**user_data)
        customer = Customer.objects.create(user=user, **validated_data)
        return customer

    def update(self, instance, validated_data):
        print "coming inside update"
        user_data = validated_data.pop("user")
        username = user_data.pop('username')
        user = get_user_model().objects.get_or_create(username=username)[0]
        user.email = user_data.get('email', user.email)
        user.save()

        instance.user = user
        instance.date_of_birth = validated_data.get('date_of_birth', instance.date_of_birth)
        instance.save()



        return instance
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
        extra_kwargs = {
            'username': {'validators': []},
        }
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
        extra_kwargs = {
            'username': {'validators': []},
        }
以下是viewset视图:

from rest_framework import viewsets

from customers.models import Customer
from customers.serializers import CustomerSerializer


class CustomerViewSet(viewsets.ModelViewSet):
    serializer_class = CustomerSerializer
    queryset = Customer.objects.all()
那么,这里有什么错呢?它创建了一个新的客户档案,甚至是新用户,但没有更新


编辑1 好的,我在UserSerializer上做了这个:

from django.contrib.auth.models import User

from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model

from rest_framework import serializers

from customers.models import Customer
from api.serializers import UserSerializer


class CustomerSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Customer
        fields = ('url', 'date_of_birth', 'user')
        depth = 1

    def create(self, validated_data):
        print "coming inside create"
        user_data = validated_data.pop("user")
        user = User.objects.create(**user_data)
        customer = Customer.objects.create(user=user, **validated_data)
        return customer

    def update(self, instance, validated_data):
        print "coming inside update"
        user_data = validated_data.pop("user")
        username = user_data.pop('username')
        user = get_user_model().objects.get_or_create(username=username)[0]
        user.email = user_data.get('email', user.email)
        user.save()

        instance.user = user
        instance.date_of_birth = validated_data.get('date_of_birth', instance.date_of_birth)
        instance.save()



        return instance
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
        extra_kwargs = {
            'username': {'validators': []},
        }
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
        extra_kwargs = {
            'username': {'validators': []},
        }
因此,对于用户字段或客户字段的所有其他字段,更新都很好,但是

  • 如果我尝试设置一个新用户名,它会创建一个全新的用户
  • 此外,在尝试创建新用户时,还会出现以下错误:

    IntegrityError at/api/客户/

    重复的键值违反唯一约束“auth\u user\u username\u key” 详细信息:密钥(用户名)=(customer1)已存在


您应该删除嵌套序列化程序的唯一验证程序:

from django.contrib.auth.models import User

from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model

from rest_framework import serializers

from customers.models import Customer
from api.serializers import UserSerializer


class CustomerSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Customer
        fields = ('url', 'date_of_birth', 'user')
        depth = 1

    def create(self, validated_data):
        print "coming inside create"
        user_data = validated_data.pop("user")
        user = User.objects.create(**user_data)
        customer = Customer.objects.create(user=user, **validated_data)
        return customer

    def update(self, instance, validated_data):
        print "coming inside update"
        user_data = validated_data.pop("user")
        username = user_data.pop('username')
        user = get_user_model().objects.get_or_create(username=username)[0]
        user.email = user_data.get('email', user.email)
        user.save()

        instance.user = user
        instance.date_of_birth = validated_data.get('date_of_birth', instance.date_of_birth)
        instance.save()



        return instance
class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
        extra_kwargs = {
            'username': {'validators': []},
        }
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'is_staff')
        extra_kwargs = {
            'username': {'validators': []},
        }

您可能需要先打印序列化程序,以确保该字段上没有其他验证器。如果您有一些,您必须将它们包括在列表中。

如果我尝试更改用户名,您的解决方案会创建一个新用户,但它当然适用于其余字段,但在尝试创建新用户时,它会抛出错误,我在问题的“编辑更新”中提到过。上面的代码删除了对用户的唯一性检查。如果要创建用户,但该用户已经存在,则必须在代码中通过引发ValidationError显式处理此约束。