Wie füge ich ein Nichtmodellfeld in einem ModelSerializer in DRF 3 hinzu? d.h. ein Feld hinzufügen, das in meinem tatsächlichen Modell nicht vorhanden ist?
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 nach Stack DRF - ModelSerializer mit einem Nicht-Modell-Feld write_only gesucht und einige Lösungen gefunden, die sich jedoch auf DRF 2 beziehen, in dem ich DRF 3 verwende. Gibt es für diese Version eine Lösung?
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 Sie diese Link
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)
return super().create(validated_data)
Die serializers.CharField(write_only=True)
und serializers.ListField(...)
sind eine gute Lösung, um Ihren .create
Und .update
Methoden zusätzliche Daten als einzelne Zeichenfolge oder als Liste von bereitzustellen Zeichenfolgen (Sie können ListField
mit anderen Serializer-Feldtypen mischen). Mit dieser Methode können Sie auch def validate_write_only_char_field
Definieren, um eine schnelle und einfache Validierung zu implementieren.
Mit serializers.SerializerMethodField()
können Sie Ihrer Serializer-Ausgabe ein benutzerdefiniertes schreibgeschütztes Feld hinzufügen, das von einer im Serializer definierten Methode stammt.
Der read_only_custom_model_field
Verwendet eine Methode für Ihr Modell, um einige Daten zu lesen, nicht ausschließlich ein Modellfeld, sondern eine benutzerdefinierte Methode. Das heißt,.
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."
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
class Foo(models.Model):
. . .
@property
def my_field(self):
return stuff
. . .
Quelle:
Django REST Framework: Hinzufügen eines zusätzlichen Felds zu ModelSerializer
Wie bereits erwähnt, gibt es zwei Möglichkeiten. (1) Hinzufügen einer Modelleigenschaft. (2) Hinzufügen eines Modellfeldes. Ich bin der Meinung, dass das Hinzufügen einer @ Eigenschaft zum Modell in diesem Beitrag gut erklärt wurde. Wenn Sie Ihre Modelle "schlank und gemein" halten möchten, verwenden Sie ein Methodenfeld. Die Antwort von Chandus lässt jedoch einige entscheidende Punkte aus:
class DeliveryItemSerializer(serializers.ModelSerializer):
product_name = serializers.SerializerMethodField(read_only=True)
def get_product_name(self, obj):
return obj.product.name
class Meta:
model = DeliveryItem
fields = (
(...your field names),
'product_name',)
get_
Feldname. Wenn Sie einen anderen Namen verwenden, verwenden Sie das Argument method_name=method
Name für SerializerMethodField()