簡體   English   中英

"django rest framework lookup_field 通過 OneToOneField"

[英]django rest framework lookup_field through OneToOneField

https:\/\/gist.github.com\/ranman\/3d97ea9054c984bca75e<\/a>

期望的行為<\/strong>
用戶查找通過用戶名進行: \/api\/users\/randall<\/code>
揚聲器查找也通過用戶名進行: \/api\/speakers\/randall<\/code>

約束<\/strong>
並非所有用戶都是演講者。 所有演講者都是用戶。

模型.py<\/strong>

from django.contrib.auth.models import User

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

這就是我設法破解它的方式

模型.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

序列化程序.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'

查看.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'

你試過這種方法嗎?

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

我正在使用用戶 ID [GET / Update] 獲取用戶設置


網址.py

path('user/<int:user_id>/settings/preferences/', UserPreferenceSettingsView.as_view(), name="settings_preferences")

模型.py

class UserSetting(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    adult_lock = models.BooleanField(default=False)
    child_lock = models.BooleanField(default=False)
    promotional_email = models.BooleanField(default=True)
    update_email = models.BooleanField(default=True)
    updated_at = models.DateTimeField(auto_now=True)

視圖.py

class UserPreferenceSettingsView(generics.RetrieveUpdateAPIView):
    http_method_names = ['get', 'patch']    
    serializer_class = UserPreferenceSettingsSerializer

    def get_object(self):
        lookup_field = self.kwargs["user_id"]
        return get_object_or_404(UserSetting, user__pk=lookup_field)

如果您需要從username獲取,只需將user_id to username替換user_id to username ,將 url <int:user_id>替換為<username> or <str:username>

我對您的代碼所做的唯一更改是通過使用用戶名而不是默認的pk<\/code>過濾來覆蓋get_object<\/code>方法。 我還將lookup_field<\/code>更改為描述性名稱,並在serializer.py<\/code>中使用了ModelSerializer<\/code>和StringRelated<\/code> 。

模型.py<\/strong>

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM