Ich möchte ein Feld zu einem Serializer hinzufügen, das spezifische Informationen für den Benutzer enthält, der die aktuelle Anfrage erstellt (ich möchte keinen separaten Endpunkt dafür erstellen). Hier ist die Art, wie ich es tue:Hinzufügen von benutzerspezifischen Feldern zum Django REST Framework-Serializer
Die Viewset:
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
filter_class = ArticleFilterSet
def prefetch_likes(self, ids):
self.current_user_likes = dict([(like.article_id, like.pk) for like in Like.objects.filter(user=self.request.user, article_id__in=ids)])
def get_object(self, queryset=None):
article = super(ArticleViewSet, self).get_object(queryset)
self.prefetch_likes([article.pk])
return article
def paginate_queryset(self, queryset, page_size=None):
page = super(ArticleViewSet, self).paginate_queryset(queryset, page_size)
if page is None:
return None
ids = [article.pk for article in page.object_list]
self.prefetch_likes(ids)
return page
Der Serializer:
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
def to_native(self, obj):
ret = super(ArticleSerializer, self).to_native(obj)
if obj:
view = self.context['view']
ret['has_liked'] = False
if hasattr(view, 'current_user_liked'):
ret['has_liked'] = obj.pk in view.current_user_liked
return ret
Gibt es einen besseren Ort, um das Prefetching von gemocht Artikeln zu injizieren, oder Einen schöneren Weg, dies generell zu tun?
Ich mag das benutzerdefinierte Feld, aber 'user_likes_article' würde im Weg Caching/Prefetching nicht in der Lage sein, viel zu tun, wenn alles, was Sie tun, gibt ihnen einen einzigen Artikel ist. Der Grund für den Prefetch in 'get_queryset' ist, dass dort alle für die Anfrage relevanten Artikel-IDs bekannt sind. Ist das Abfrage-Set in dem Serialisierungsfeld irgendwie verfügbar? –
Ich nehme an, Sie würden den einzelnen Artikel-Parameter verwenden, um den Artikel aus einer (zwischengespeicherten) Sammlung von user_likes (oder so) auszuwählen. Ihr QuerySet ist nur Articles.objects.all() richtig? Es gibt dort keine spezifischen Anforderungen, aber genau wie Sie user_likes_article implementieren, hängt (natürlich) davon ab, was genau Sie tun möchten. –
Ich erkannte, dass es in meiner ursprünglichen Frage einen ernsten Fehler gab; Die Filtersatz- oder Seitenumbruch-Abfrage wurde nicht berücksichtigt. Ich habe es jetzt geändert, und ich denke, es macht ein bisschen mehr Sinn. Sie können sehen, wie das Prefetching eng mit der Anfrage gekoppelt ist (Filterung und Paginierung) und dass ich es nicht einfach in das Like-Modell verschieben kann. –