2015-11-08 9 views
2

У меня есть большое недоразумение с вложенными сериализаторами DRF. Я прочитал документы об этом и узнал, что мне нужно предоставить свой собственный метод обновления. Итак, вот оно:Обновление Django Rest Framework вложенной сериализатор

class SkillsSerializer(serializers.ModelSerializer): 

class Meta: 
    model = Skills 

class ProfileSerializer(serializers.ModelSerializer): 
    skills = SkillsSerializer(many=True) 

    class Meta: 
     model = Profile 
     fields = ('user', 'f_name', 'l_name', 'bd_day', 'bd_month', 'bd_year', 'spec', 'company', 'rate', 'skills', 'bill_rate', 'website', 'about', 'city', 'avatar', 'filled') 

    def update(self, instance, validated_data): 
     instance.user_id = validated_data.get('user', instance.user_id) 
     instance.f_name = validated_data.get('f_name', instance.f_name) 
     instance.l_name = validated_data.get('l_name', instance.l_name) 
     instance.bd_day = validated_data.get('bd_day', instance.bd_day) 
     instance.bd_month = validated_data.get('bd_month', instance.bd_month) 
     instance.bd_year = validated_data.get('bd_year', instance.bd_year) 
     instance.spec = validated_data.get('spec', instance.spec) 
     instance.company = validated_data.get('company', instance.company) 
     instance.rate = validated_data.get('rate', instance.rate) 
     instance.website = validated_data.get('website', instance.website) 
     instance.avatar = validated_data.get('avatar', instance.avatar) 
     instance.about = validated_data.get('about', instance.about) 
     instance.city = validated_data.get('city', instance.city) 
     instance.filled = validated_data.get('filled', instance.filled) 
     instance.skills = validated_data.get('skills', instance.skills) 
     instance.save() 
     return instance 

Я сравнил его с документами и не нашел разницы. Но в этом случае, когда я пытаюсь обновить навыки, это не сработает. И есть настоящая магия: когда я положил это

instance.skills = validated_data.get('bd_day', instance.skills) 

Это работает ОТЛИЧНО ХОРОШО! Например, если я положил bd_day = 12, метод обновления сохраняет экземпляр с навыками с идентификаторами 1 и 2. Итак, похоже, что сериализатор игнорирует навыки из данных AJAX и все еще думает, что сериализатор навыков читается только. Итак, что такое эта логика и как я могу наконец обновить свои навыки?

UPDATE

Мои модели:

class Skills(models.Model): 
    tags = models.CharField(max_length='255', blank=True, null=True) 

    def __unicode__(self): 
     return self.tags 


class Profile(models.Model): 
    user = models.OneToOneField(User, primary_key=True) 
    ... 
    skills = models.ManyToManyField(Skills, related_name='skills') 
    ... 

UPDATE2

Тем не менее, не имеет решения для этого случая! Я пробовал this и this - тот же результат. Кажется, что сериализатор вообще игнорировал данные JSON.

+0

Каковы области модели Навыки и каковы типы данных каждого поля? –

+0

@ArpitGoyal - я обновил свой вопрос. – NONAMA

+0

Какие данные вы отправляете в точку API? – Linovia

ответ

1

У вас есть проблема здесь, поскольку вы предоставляете немодельные данные.

это:

instance.skills = validated_data.get('skills', instance.skills) 

не будет предоставлять экземпляры модели Skill, но словарь. Сначала вам нужно получить экземпляр навыков, а затем ввести их обратно в instance.skills.

+0

Не могли бы вы привести пример, как это должно выглядеть? – NONAMA

+0

В документации уже есть одно: http://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers – Linovia

+1

Это так, но я не нашел пример для метода обновления для многих -то-многие без таблицы. – NONAMA

1

FINALLY! Я нашел решение для своей задачи.

Я создал два отдельных сериализатора, один для GET и другой для PUT/PATCH.

class ProfileSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = Profile 
     fields = ('user', 'f_name', ... 'skills', ... 'filled') 
     depth = 1 

class ProfileUpdateSerializer(serializers.ModelSerializer): 
    skills = serializers.PrimaryKeyRelatedField(many=True, queryset=Skills.objects.all(), required=False) 

    class Meta: 
     model = Profile 
     fields = ('user', 'f_name', ... 'skills', ... 'filled') 

    def update(self, instance, validated_data): 
     instance.user_id = validated_data.get('user', instance.user_id) 
     instance.f_name = validated_data.get('f_name', instance.f_name) 
    .... 
     instance.skills = validated_data.get('skills') 
     instance.save() 
     return instance 

Но после этого у меня была другая проблема. Я могу получить только один элемент из массива навыков. И я нашел решение здесь:

$.ajax({ 
    url: myurl, 
    type: 'PUT', 
    dataType: 'json', 
    traditional: true,<-----THIS! 
    data: data, 

И все! Отлично работает!

Надеюсь, мое решение будет полезно!

+0

У меня такая же проблема, но я не думаю, что создание двух сериализаторов идеально по DRY. Любые новые идеи? – vabada

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