2

我在Django中扩展了用户模型,它是Customer类型的。我正在使用django rest框架(DRF)。因此,虽然通过DRF文档去我来了解嵌套模式写作,所以它说我没有覆盖创建和串行更新方法,创建工作正常,但不是更新:Django rest框架没有更新扩展用户模型

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 

这里是视图集视图:

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:

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

因此,更新是罚款,如果我用户或客户领域的所有其他领域,但

  • 尝试设置一个新的用户名,它会创建一个全新的用户,
  • 并且在尝试创建新用户时,它会给出foll由于错误:密钥(用户名)=(customer1表)已经存在:在/ API /客户/

    重复键值违反唯一约束 “auth_user_username_key” DETAIL

    IntegrityError。

回答

2

你应该放弃的唯一校验器嵌套串行:

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

您可能需要打印串行之前,为了确保你没有在该领域其他验证。如果你有一些,你必须将它们包括在列表中。

+0

您的解决方案,如果我尝试更改用户名,创建一个新用户,但当然它适用于其余的字段,但试图创建新的用户,它会引发错误,我在编辑更新我提到的问题。 – Maverick

+0

上面的代码删除了用户的唯一性检查。如果您要创建用户但已存在,则必须在代码中明确处理此约束,方法是引发ValidationError。 – Linovia