Django REST-Framework 3.0+
Dynamische Felder jetzt unterstützt werden, finden http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields - dieser Ansatz alle Felder in der Serializer definiert, und dann können Sie selektiv diejenigen, entfernen Sie nicht wollen.
Oder Sie könnten auch für ein Modell Serializer etwas tun, wo man herumspielen mit Meta.fields im Serializer init:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('code',)
def __init__(self, *args, **kwargs):
if SHOW_CLASSIFICATION: # add logic here for optional viewing
self.Meta.fields = list(self.Meta.fields)
self.Meta.fields.append('classification')
super(ProductSerializer, self).__init__(*args, **kwargs)
Sie haben würde Tom fragen aber, wenn dies ist die " richtiger Weg ", da es möglicherweise nicht in den langfristigen Plan passt.
Django REST-Framework < 3.0
versuchen, etwas wie folgt aus:
class ProductSerializer(serializers.Serializer):
...
classification = serializers.SerializerMethodField('get_classification')
def get_classification(self, obj):
return getattr(obj, 'classification', None)
Multiple Serializer
Ein anderer Ansatz wäre, mehrere Serializer mit verschiedenen Sätzen von Feldern zu erstellen. Ein Serializer erbt von einem anderen und fügt zusätzliche Felder hinzu. Dann können Sie in der Ansicht mit der Methode get_serializer_class
den entsprechenden Serializer auswählen. Hier ist ein aktuelles Beispiel dafür, wie ich mit diesem Ansatz verschiedene Serializer aufrufen kann, um unterschiedliche Benutzerdaten darzustellen, wenn das Benutzerobjekt mit dem Anforderungsbenutzer identisch ist.
def get_serializer_class(self):
""" An authenticated user looking at their own user object gets more data """
if self.get_object() == self.request.user:
return SelfUserSerializer
return UserSerializer
Entfernen von Feldern aus Darstellung
Einen anderen Ansatz, den ich in Sicherheitskontexten verwendet habe, sind Felder in den to_representation
Verfahren zu entfernen. Definieren Sie eine Methode, wie
def remove_fields_from_representation(self, representation, remove_fields):
""" Removes fields from representation of instance. Call from
.to_representation() to apply field-level security.
* remove_fields: a list of fields to remove
"""
for remove_field in remove_fields:
try:
representation.pop(remove_field)
except KeyError:
# Ignore missing key -- a child serializer could inherit a "to_representation" method
# from its parent serializer that applies security to a field not present on
# the child serializer.
pass
und dann in Ihrem Serializer, rufen Sie diese Methode wie
def to_representation(self, instance):
""" Apply field level security by removing fields for unauthorized users"""
representation = super(ProductSerializer, self).to_representation(instance)
if not permission_granted: # REPLACE WITH PERMISSION LOGIC
remove_fields = ('classification',)
self.remove_fields_from_representation(representation, remove_fields)
return representation
Dieser Ansatz ist einfach und flexibel, aber es kommt auf Kosten der Serialisierung Felder, die manchmal nicht angezeigt werden. Aber das ist wahrscheinlich in Ordnung.
Ist es akzeptabel, für diese Felder als 'None' serialisiert werden, oder sollte der Schlüssel gar nicht vorhanden sein? –
Sie sind überhaupt nicht vorhanden, ich rufe einen SOAP-Webdienst auf, der optionale Felder mit suds hat, das Antwortobjekt stellt das zurückgegebene XML dar, das in bestimmten Fällen das optionale Feld nicht enthält. – abstractpaper
Tom Ich habe gerade realisiert, was du meintest; Idealerweise möchte ich, dass sie gar nicht anwesend sind, aber ich kann vorläufig mit "None" leben. – abstractpaper