2

У меня есть расширенная модель пользователя в Django, и она имеет тип клиента. Я использую django rest framework (DRF). Таким образом, в то время как происходит через документы в ФПИ я узнал о написании в вложенных моделей, так что я переопределение Методы создания и обновления в сериализатором, создание работает нормально, но не обновление, как он говорит:Django rest framework не обновляет расширенную модель пользователя

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 

Вот вид 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() 

Итак, что может быть неправильно здесь, что он создает новый профиль клиента даже новый пользователь, но не обновляется?


Edit 1 Ok, так что я сделал это на UserSerializer:

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

Таким образом, обновление отлично подходит для всех других областях пользователей или клиентов полей, но

  • , если я попробуйте установить новое имя пользователя, он создает совершенно нового пользователя,
  • , а также при попытке создать нового пользователя он дает fo Ошибка llowing:

    IntegrityError в/API/клиенты/

    дубликат ключа значение нарушает ограничение уникальности "auth_user_username_key" ДЕТАЛЬ: Ключ (имя пользователя) = (customer1) уже существует.

ответ

2

Вы должны уронить уникальный валидатор для вложенного сериализатора:

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

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

+0

Ваше решение создает нового пользователя, если я пытаюсь изменить имя пользователя, но, конечно, он работает для остальной части полей, но при попытке создать нового пользователя он вызывает ошибку, о которой я упоминал в редактировании обновления моего вопроса , – Maverick

+0

Вышеприведенный код удаляет проверку на уникальность пользователя. Вам придется иметь дело с этим ограничением явно в вашем коде, подняв ValidationError, если вы собираетесь создать пользователя, но он уже существует. – Linovia

 Смежные вопросы

  • Нет связанных вопросов^_^