2015-06-02 5 views
11

Jak dodać pole modelu inne niż w ModelSerializer w DRF 3? tj. dodać pole, które nie istnieje w moim rzeczywistym modelu?Dodawanie pola innego niż model w ModelSerializer w DRF 3

class TestSerializer(serializers.ModelSerializer): 
    url = serializers.HyperlinkedIdentityField(view_name='vote_detail') 
    non_field = serializers.CharField() # no corresponding model property. 


    class Meta: 
     model = vote_model 
     fields = ("url", "non_field") 

    def create(self, validated_data): 
     print(direction=validated_data['non_field']) 

Ale DRF 3 daje mi błąd:

Got AttributeError when attempting to get a value for field `non_field` on serializer `TestSerializer`. 
The serializer field might be named incorrectly and not match any attribute or key on the `Test` instance. 
Original exception text was: 'Test' object has no attribute 'non_field'. 

Przeszukałem stos DRF - ModelSerializer with a non-model write_only field i znalazłem kilka rozwiązań, ale odnoszą się one do FRD 2, gdzie używam DRF 3. Czy istnieje rozwiązanie do tego w tej wersji?

+1

https://github.com/tomchristie/django-rest-framework/issues/840 – chandu

+1

http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield – chandu

+0

@ chandu więc problem jest w trakcie, ponieważ nie został on naprawiony w wersji 3.0+ lub czy istnieje teraz rozwiązanie tego problemu? – Prometheus

Odpowiedz

6
class TestSerializer(serializers.ModelSerializer): 
    url = serializers.HyperlinkedIdentityField(view_name='vote_detail') 
    non_field = serializers.SerializerMethodField() # no corresponding model property. 

    class Meta: 
     model = vote_model 
     fields = ("url", "non_field") 

    def create(self, validated_data): 
     print(direction=validated_data['non_field']) 

http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield

lub przejść przez ten link

+0

non_field = serializers.serializers.SerializerMethodField() # brak odpowiadającej właściwości modelu - usuń dodatkowe serializery. ? – Liz

+1

Próbuję zrobić dokładnie to samo, ale mam błąd informujący mnie, że mój model nie ma tego pola. Czy ktoś znalazł rozwiązanie? – Ben

+0

@Bądź to samo tutaj. – levi

2

Tylko przykład może ci pomóc.

class ExtensibleModelSerializerOptions(serializers.SerializerOptions): 
    """ 
    Meta class options for ModelSerializer 
    """ 
    def __init__(self, meta): 
     super(ExtensibleModelSerializerOptions, self).__init__(meta) 
     self.model = getattr(meta, 'model', None) 
     self.read_only_fields = getattr(meta, 'read_only_fields',()) 
     self.non_native_fields = getattr(meta, 'non_native_fields',()) 


class ExtensibleModelSerializer(serializers.ModelSerializer): 

    _options_class = ExtensibleModelSerializerOptions 

    def restore_object(self, attrs, instance=None): 
     """ 
     Deserialize a dictionary of attributes into an object instance. 
     You should override this method to control how deserialized objects 
     are instantiated. 
     """ 
     for field in self.opts.non_native_fields: 
      attrs.pop(field) 

     return super(ExtensibleModelSerializer, self).restore_object(attrs, instance) 

Źródło: https://github.com/tomchristie/django-rest-framework/issues/951

15
class MySerializer(serializers.ModelSerializer): 
    write_only_char_field = serializer.CharField(write_only=True) 
    write_only_list_char_field = serializer.ListField(child=serializers.CharField(max_length=100, default=''), write_only=True) 
    empty_method_field = serializers.SerializerMethodField() 
    read_only_custom_model_field = serializers.CharField(source='custom_property', read_only=True) 

    def create(self, validated_data): 
     validated_data.pop('write_only_char_field', None) 
     validated_data.pop('write_only_list_char_field', None) 

serializers.CharField(write_only=True) i serializers.ListField(...) jest dobrym rozwiązaniem, aby dostarczyć dodatkowych danych do .create i .update metod, albo jako jeden ciąg znaków lub listy ciągów (można mieszać ListField z innej dziedzinie serializer typy). Za pomocą tej metody można również zdefiniować def validate_write_only_char_field, aby przeprowadzić szybką i prostą weryfikację.

serializers.SerializerMethodField() Umożliwia dodanie niestandardowego pola tylko do odczytu do danych wyjściowych serializera z metody zdefiniowanej w module serializera.

Użyłby metody w twoim modelu, aby odczytać dane, a nie tylko pole modelu, ale metodę niestandardową. To znaczy.

class MyModel(models.Model): 
    my_field = models.CharField(max_length=100) 

    @property 
    def custom_property(self): 
     return "Perform calculations, combine with related models, etc. etc."