2017-01-30 10 views
0

В настоящее время я использую успокоительные и сериализаторы для создания и обновления моего пользователя. Почему-то я не могу обновить некоторые поля, если это поле имеет отношение к OneToOneField/ForeignKey.Как обновить OneToOneField/ForeignKey с помощью ViewSet? Django

в моем models.py, мой студент фактически подключен к Джанго построить в пользовательской модели, которая включает в себя электронную почту пользователя и подключены к модели школы, которая имеет название школы

class Student(Model): 
    user = OneToOneField(settings.AUTH_USER_MODEL, on_delete=CASCADE) 

    date_of_birth = DateField(blank=True, null=True) 

    student_name = CharField(max_length=256) 
    school = ForeignKey(School, 
         on_delete=CASCADE, 
         related_name="%(class)ss", 
         related_query_name="%(class)s", 
         blank=True, 
         null=True) 

в сериализаторе. ру у меня есть

class StudentSerializer(ModelSerializer): 
    user_email = SerializerMethodField() 
    school_name = SerializerMethodField() 

    class Meta: 
     model = Student 
     fields = (
      'user_email', 'student_name', 'phone', 'school_name') 

    def get_user_email(self, obj): 
     return obj.user.email 

    def get_school_name(self, obj): 
     return obj.school.school_name 

    def create(self, validated_data): 
     return Student.objects.create(**validated_data) 

    def update(self, instance, validated_data): 
     instance.user.email = validated_data.get('user_email', instance.user.email) 
     instance.student_name = validated_data.get('student_name', instance.student_name) 
     instance.phone = validated_data.get('phone', instance.phone) 
     instance.school.school_name = validated_data.get('school_name', instance.school.school_name) 
     instance.save() 
     return instance 

в моей view.py функции обновления

class UserViewSet(ViewSet): 
    queryset = Student.objects.all() 

    def update(self, request, pk=None): 
     student = get_object_or_404(self.queryset, pk=pk) 
     serializer = StudentSerializer(student, data=request.data, partial=True) 
     if serializer.is_valid(): 
      serializer.save() 
      return Response({'status': True}) 
     return Response({'status': False, 'message': serializer.errors}) 

I я могу использовать представление API для передачи в json и обновлять student_name и phone, но как и для двух других, user_email и school_name Я не могу его обновить. Я не получаю никаких ошибок при отправке json.

Я понял, что два поля, которые я не могу обновить, - это то, что они OneToOneField/ForeignKey.

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

Заранее спасибо

+0

'instance..school.school_name', вы просто опечатка в этом StackOverflow или в сценарии ? –

+0

@SancaKembang in stackoverflow: P – Dora

ответ

0

Вложенные seriailzer/model/presentation на самом деле помогли мне получить работу и очень полезно.

Приведен также пример. http://www.django-rest-framework.org/api-guide/serializers/#writing-update-methods-for-nested-representations

выше продолжается от http://www.django-rest-framework.org/api-guide/serializers/#writing-create-methods-for-nested-representations, который содержал как вложенная сериализатору это время установки в полях класса и мета-х

0

Поскольку вы используете SerializerMethodField, который доступен только для чтения поле (docs) для user_email и school_name так что они не будут доступны в validated_data.

Вы проверить данные, вы получаете в validated_data

def update(self, instance, validated_data): 
    print('++'*22, validated_data) 
    return instance 
0

Я думаю, что ваш сериализатору не завершен ... поле user и school является экземпляром модели, вам нужно конкретное поле в serializer для реализации модели экземпляра, например: с аргументом source='...'.

и пример:

class VoteSerializer(serializers.ModelSerializer): 
    # by `username` 
    user = serializers.CharField(
     source='user.username', 
     read_only=True 
    ) 
    # by `pk/id` 
    candidate = serializers.IntegerField(
     source='candidate.pk', 
     read_only=True 
    ) 

    class Meta: 
     model = Vote 
     fields = ('user', 'candidate', 'score') 

    def create(self, validated_data): 
     return Vote.objects.create(**validated_data) 

и в вашем случае, может быть, как это;

class StudentSerializer(ModelSerializer): 
    # by `pk/id` from the user 
    user = serializers.IntegerField(
     source='user.pk', 
     read_only=True 
    ) 
    school = serializers.IntegerField(
     source='school.pk', 
     read_only=True 
    ) 
+0

Я просто пробовал это, хотя и, конечно, мне нужно использовать 'user_email' с' EmailField' вместо того, что вам нужно, но все равно не повезло. У меня нет ошибок при попытке его обновления. – Dora