2015-10-29 5 views
1

Я хочу обновить записи, связанные с внешними ключами или связанные любыми способами. Я знаю, как обновлять записи одной модели, но я не могу сделать то же самое в случае связанных моделей.Обновления Записи, связанные с внешним ключом В Django Rest

Мои модели:

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    subject = models.ManyToManyField('Subjects') 
    phone = models.CharField(max_length=20) 
    address = models.TextField() 

    def __unicode__(self): 
     return self.user.username 

class Subjects(models.Model): 
    name = models.CharField(max_length=100) 
    code = models.IntegerField() 


    def __unicode__(self): 
     return self.name 

Мои сериализаторы:

class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = (
       'id', 
       'first_name', 
       'username', 
       'email', 
       'is_active', 
      ) 

class SubjectSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Subjects 
     fields = (
       'name', 
       'code', 
      ) 

class UserProfileSerializer(serializers.ModelSerializer): 
    user = UserSerializer() 
    subject = SubjectSerializer(many=True) 

    class Meta: 
     model = UserProfile 
     fields = (
       'user', 
       'subject', 
       'phone', 
       'address', 
      ) 

Просмотров:

class UserProfileList(viewsets.ModelViewSet): 
    serializer_class = UserProfileSerializer 

    queryset = UserProfile.objects.all() 

URLs

router.register(r'api/user/profile', UserProfileList) 

Я могу увидеть первую запись как /api/user/profile/1/ Но когда я пытаюсь обновить запись из BROWSABLE Rest Апи это дает мне ошибку user with same username already exist.

Edit:

Я хочу обновить UserProfile модель используя UserProfileSerializer. Просто создайте новые записи, обновите существующий и удалите.

ответ

0

У вас есть ограничение на имя пользователя, которое делает невозможным создание снова. Необходимо удалить это, изменив валидаторы UserSerializer.username. Убедитесь, что вы не удалить другие ограничения, напечатав сериалайзер:

>>> print(UserSerializer()) 
>>> UserSerializer(): 
    id = IntegerField(label='ID', read_only=True) 
    first_name = CharField(allow_blank=True, max_length=30, required=False) 
    username = CharField(help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, validators=[<django.core.validators.RegexValidator object>, <UniqueValidator(queryset=User.objects.all())>]) 
    email = EmailField(allow_blank=True, label='Email address', max_length=254, required=False) 
    is_active = BooleanField(help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', label='Active', required=False) 

Как вы можете заметить, у нас есть UniqueValidator на имя пользователя, а также RegexValidator

Вам нужно изменить класс:

from django.core import validators 
from django.utils.translation import ugettext_lazy as _ 

class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = (
      'id', 
      'first_name', 
      'username', 
      'email', 
      'is_active', 
     ) 
     extra_kwargs = { 
      'username': { 
       'validators': [ 
        validators.RegexValidator(
         r'^[\[email protected]+-]+$', 
         _('Enter a valid username. This value may contain only ' 
         'letters, numbers ' 'and @/./+/-/_ characters.') 
       ),] 
      } 
     } 

Обратите внимание, что валидатор здесь берется из определения Джанго этого поля (https://github.com/django/django/blob/master/django/contrib/auth/models.py#L309)

Теперь, если вы печатаете снова сериализатору вы должны увидеть, что единственное ограничение снимается:

>>> print(UserSerializer()) 
>>> UserSerializer(): 
    id = IntegerField(label='ID', read_only=True) 
    first_name = CharField(allow_blank=True, max_length=30, required=False) 
    username = CharField(help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, validators=[<django.core.validators.RegexValidator object>]) 
    email = EmailField(allow_blank=True, label='Email address', max_length=254, required=False) 
    is_active = BooleanField(help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', label='Active', required=False) 
+0

если ограничение уникальности удаляется, то он будет обновлять ту же запись или добавить NewOne? – saf

+0

Это ваша работа, чтобы сделать это в функции создания/обновления serializer. Например, см. Http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers. Причина в том, что существует слишком много возможных вариантов использования, поэтому DRF позволяет разработчику справиться с этим. – Linovia

+0

ok Я проверю это – saf

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