2015-06-02 8 views
11

Wie fügt man ein Nicht-Modellfeld in DRF 3 zu einem ModelSerializer hinzu? d. h. ein Feld hinzufügen, das auf meinem tatsächlichen Modell nicht existiert?Hinzufügen eines Nicht-Modellfelds auf einem ModelSerializer in 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']) 

Aber DRF 3 gibt mir den Fehler:

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'. 

Ich habe gesucht Stapel DRF - ModelSerializer with a non-model write_only field und fand einige Lösungen, aber diese beziehen sich auf DRF 2, wo ich 3 bin mit DRF Gibt es eine Lösung dafür auf dieser Version?

+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 ist also das Problem zu gehen, wie es in 3.0+ nicht behoben ist oder gibt es jetzt eine Lösung für dieses Problem? – Prometheus

Antwort

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

oder gehen durch diese link

+0

non_field = serializers.serializers.SerializerMethodField() # keine entsprechende Modelleigenschaft - entfernen Sie die zusätzlichen Serializer. ? – Liz

+1

Ich versuche genau das gleiche zu tun, aber ich habe einen Fehler, der mir sagt, dass mein Modell dieses Feld nicht hat. Hat jemand eine Lösung gefunden? – Ben

+0

@Ben gleich hier. – levi

2

Nur ein Beispiel könnte Ihnen helfen.

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) 

Quelle: 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) 

Die serializers.CharField(write_only=True) und serializers.ListField(...) ist eine gute Lösung, zusätzliche Daten zu Ihren .create und .update Methoden zur Verfügung zu stellen, entweder als eine einzelne Zeichenfolge oder eine Liste von Strings (Sie ListField mit anderen Serializer Feld mischten Arten). Mit dieser Methode können Sie auch def validate_write_only_char_field definieren, um eine schnelle und einfache Validierung zu implementieren.

serializers.SerializerMethodField() können Sie ein benutzerdefiniertes schreibgeschütztes Feld zu Ihrer Serializer-Ausgabe von einer auf dem Serializer definierten Methode hinzufügen.

Die read_only_custom_model_field würde eine Methode auf Ihrem Modell verwenden, um einige Daten zu lesen, nicht nur ein Modellfeld, sondern eine benutzerdefinierte Methode. I.e.

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." 
Verwandte Themen