2017-07-23 4 views
1

Ich möchte meine Besucher Funktion zum Erstellen und Liste der Vorschläge erhalten.Django Rest Framework geschachtelte Objekte erstellen mit request.user

Benutzer alle Daten außer dem Autor Vorschlag senden (weil die Auth-Benutzer selbst ist), so versuche ich, request.data mit request.user wie folgt zu erweitern:

# proposals/views.py 
class ProposalsList(ListCreateAPIView): 
    permission_classes = (IsAuthenticatedOrReadOnly,) 
    queryset = Proposal.objects.all() 
    serializer_class = ProposalSerializer 

    def post(self, request, *args, **kwargs): 
     serializer = self.get_serializer(data={ 
      **request.data, 
      "author": request.user.id, 
      }) 
      serializer.is_valid(raise_exception=True) 
      self.perform_create(serializer) 
      headers = self.get_success_headers(serializer.data) 
      return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) 

Obwohl, ich möchte die Vorschläge Liste mit serialisierten Autor (Benutzer) bekommen, so meine Serializer wie folgt aussieht:

# proposals/serializers.py 
class ProposalSerializer(serializers.ModelSerializer): 
    author = UserSerializer() 
    class Meta: 
     model = SeekerProposal 
     fields = ('text', 'author') 

Das Problem ist, dass ich GET Benutzer korrekt Liste (serialisiert dict), aber ich kann nicht POST (Neues erstellen) Angebot, weil es t o "Autor" sei ein Diktat (es passiert, weil ich verschachtelte Serializer Autor = UserSerializer() verwende).

Fragen:

  1. Gibt es eine Möglichkeit Ansicht ListCreateAPIView und Autor = UserSerializer() sein zu lassen, während die Liste GET mit serialisierten Daten und erstellen Vorschlag request.user.id?
  2. Vielleicht gibt es eine andere Möglichkeit, autorisierten Benutzer zu Proposal Autor Feld hinzufügen?

Auch dies ist mein Modell:

# proposals/models.py 
class Proposal(models.Model): 
    text = models.TextField(blank=False, null=False) 
    author = models.ForeignKey(
     settings.AUTH_USER_MODEL, 
     on_delete=models.SET(get_sentinel_user), 
    ) 

Antwort

Benutzer @zaidfazil mir mit Lösung geholfen. Ich brauchte nur noch ein zusätzliches Feld zu meinem Serializer hinzufügen Verfasser Details serialisiert gezeigt werden:

# proposals/serializers.py 
class ProposalSerializer(serializers.ModelSerializer): 
    author_details = UserSerializer(source='author', read_only=True) 
    class Meta: 
     model = SeekerProposal 
     # author will be user id, and author_details will be serialized dict 
     fields = ('text', 'author', 'author_details') 

Da author noch id nur Benutzer und author_details ist read_only=True ich für Autor in GET Anfrage alle Daten erhalten und kann einen neuen Vorschlag von author=request.user.id erstellen.

Einen Moment:

ich nicht blank=True auf author Feld verwendet habe, weil ich sicher sein, dass dieses Feld nicht leer ist. So sieht meine Ansicht genauso aus wie oben geschrieben (post auf ProposalsList).

Nochmals vielen Dank an @zaidfazil! Wenn ich etwas falsch geschrieben habe, schreibe mir bitte, ich bin irgendwie nooby auf stackoverflow.

+0

Irgendeine Art von Antwort wurde die Schaffung neuer Serializer ProposalNestedSerializer genannt, die meine ProposalSerializer erbt und sich author = UserSerializer(), während es von ProposalSerializer entfernen. So, jetzt benutze ich ProposalNestedSerializer für GET (und serialisierten Autor als Antwort bekommen) und mit ProposalSerializer mit POST (und kann Vorschläge nur mit request.user.id erstellen) – Dionid

Antwort

0

gewohnter Weise würde Ihre author Feld als blank=True in Ihren Modellen und Leiten des Benutzers werden definiert, wenn die Serializer Speichern

author = models.ForeignKey(settings.AUTH_USER_MODEL, 
    on_delete=models.SET(get_sentinel_user), blank=True) 

Serializer.py,

class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('email', 'first_name', .....) 

class ProposalSerializer(serializers.ModelSerializer): 
    author_details = UserSerializer(source='author', read_only=True) 
    class Meta: 
     model = SeekerProposal 
     fields = ('text', 'author', 'author_details') 

Dann Ihrer Ansicht nach

class ProposalsList(ListCreateAPIView): 
    permission_classes = (IsAuthenticatedOrReadOnly,) 
    queryset = SeekerProposal.objects.all() 
    serializer_class = SeekerProposalSerializer 

    def perform_create(self, serializer): 
     serializer.save(author=self.request.user) 
+0

Vielen Dank! Aber es gibt noch Probleme: Erstens, auf GET brauche ich eine Liste von Vorschlägen mit serialisierten Autor und auf POST erstellen Vorschlag mit author = request.user.id (aber ich kann nicht, denn wenn ich author = UserSerializer() in ProposalSerializer fragt nach Objekt beim Erstellen) Zweitens, ich möchte nicht Autor leer machen = True, weil es ein bisschen Gefahr ist (Ich brauche Auth für viele Situationen) – Dionid

+0

Autor 'blank = True' würde keinen Effekt verursachen , cuz Zuweisung von Benutzer wird nur von hinter den Kulissen behandelt werden. Andernfalls würde die Sicherheit selbst verloren gehen, auch das Feld "Benutzer" ist weiterhin obligatorisch. Für Ihre Frage zu den Autorendetails können Sie in der GET-Anfrage ein 'read_only'-Feld hinzufügen, um die Details der vorhandenen Autoreninformationen anzuzeigen. Ich werde meine Antwort in Kürze aktualisieren. – zaidfazil

+0

Sie gaben mir Weg, um dieses Problem zu lösen! Ich werde es in meiner Frage beschreiben. Aber zwei Dinge: Ich muss sicher sein, dass der Autor nicht leer ist, also möchte ich wirklich nicht "blank = True" verwenden und ich tat es nicht, auch können Sie "author_details" hinzufügen, um Ihre Antwort für andere zu tupeln nicht verwirrt sein, warum sie Fehler bekommen) – Dionid

Verwandte Themen