wake-up-neo.com

django rest framework lookup_field durch OneToOneField

https://Gist.github.com/ranman/3d97ea9054c984bca75d

Gewünschtes Verhalten
Die Suche des Benutzers erfolgt anhand des Benutzernamens: /api/users/randall
Die Suche nach Sprechern erfolgt ebenfalls über den Benutzernamen: /api/speakers/randall

Einschränkungen
Nicht alle Benutzer sind Sprecher. Alle Referenten sind Benutzer.

models.py

from Django.contrib.auth.models import User

class Speaker(models.Model):
    user = models.OneToOneField(User)

serializers.py

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups')
        lookup_field = 'username'

class SpeakerSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        read_only=True,
        lookup_field='username'
    )
    class Meta:
        model = Speaker
        lookup_field = 'user'

views.py

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'username'

class SpeakerViewSet(viewsets.ModelViewSet):
    queryset = Speaker.objects.all().select_related('user')
    serializer_class = SpeakerSerializer
    lookup_field = "user"

Ich habe verschiedene Aufrufe von Lookup_field- und Serialisierertypen ausprobiert, damit dies nicht funktioniert. Ohne viel mehr Code ist dies möglicherweise nicht möglich. Ich frage mich nur, in welche Richtung ich gehen kann.

Vielen Dank!

13
Randall Hunt

So habe ich es geschafft, es zu hacken

models.py

from Django.db import models    
from Django.contrib.auth.models import User

class Speaker(models.Model):
    user = models.OneToOneField(User)

    @property
    def user__username(self):
        return self.user.username

    def __unicode__(self):
        return self.user.username

serializers.py

from .models import Speaker
from rest_framework import serializers
from Django.contrib.auth.models import User

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups')
        lookup_field = 'username'

class SpeakerSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.HyperlinkedRelatedField(
        view_name='user-detail',
        read_only=True,
        lookup_field='username'
    )
    class Meta:
        model = Speaker
        fields = ('url', 'user')
        lookup_field = 'user__username'

view.py

from .models import Speaker
from .serializers import SpeakerSerializer, UserSerializer

from rest_framework import viewsets
from Django.contrib.auth.models import User

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'username'

class SpeakerViewSet(viewsets.ModelViewSet):
    queryset = Speaker.objects.all().select_related('user')
    serializer_class = SpeakerSerializer
    lookup_field = 'user__username'
7
Todor

Hast du diesen Ansatz ausprobiert?

class SpeakerViewSet(viewsets.ModelViewSet):
    queryset = Speaker.objects.all().select_related('user')
    serializer_class = SpeakerSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('user', 'user__username',)
0
mariodev