2015-06-02 6 views
11

Come aggiungere un campo non modello a ModelSerializer in DRF 3? Ad esempio, aggiungi un campo che non esiste sul mio modello attuale?Aggiungere un campo non modello su un 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']) 

Ma DRF 3 mi dà l'errore:

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

Ho cercato di stack DRF - ModelSerializer with a non-model write_only field e trovato alcune soluzioni, ma queste si riferiscono a DRF 2 dove sto usando DRF 3. C'è una soluzione per questo su questa versione?

+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 quindi è il problema su come non è stato risolto in 3.0+ o c'è ora una soluzione a questo? – Prometheus

risposta

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

o passare attraverso questo link

+0

non_field = serializers.serializers.SerializerMethodField() # nessuna proprietà modello corrispondente: rimuovere i serializzatori aggiuntivi. ? – Liz

+1

Sto provando a fare esattamente la stessa cosa ma ho un errore che mi dice che il mio modello non ha questo campo. Qualcuno ha trovato una soluzione? – Ben

+0

@Ben stesso qui. – levi

2

Solo un esempio potrebbe aiutarti.

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) 

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

Il serializers.CharField(write_only=True) e serializers.ListField(...) è una buona soluzione per fornire dati aggiuntivi alle vostre .create e .update metodi, sia come una singola stringa o una lista di stringhe (potete mescolare ListField con altro campo serializzatore tipi). Con questo metodo è inoltre possibile definire def validate_write_only_char_field per implementare alcune convalide semplici e veloci.

serializers.SerializerMethodField() consente di aggiungere alcuni campi personalizzati di sola lettura all'output del serializzatore da un metodo definito sul serializzatore.

Il read_only_custom_model_field utilizza un metodo sul modello per leggere alcuni dati, non solo un campo modello, ma un metodo personalizzato. Cioè

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." 
Problemi correlati