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