简体   繁体   English

"django rest framework lookup_field 通过 OneToOneField"

[英]django rest framework lookup_field through OneToOneField

This is how i managed to hack it这就是我设法破解它的方式

models.py模型.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序列化程序.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查看.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'

Have you tried this approach?你试过这种方法吗?

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

I'm fetching user's settings with user's ID [GET / Update]我正在使用用户 ID [GET / Update] 获取用户设置


urls.py网址.py

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

models.py模型.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)

views.py视图.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)

If you need to fetch from username just replace user_id to username and url <int:user_id> to <username> or <str:username>如果您需要从username获取,只需将user_id to username替换user_id to username ,将 url <int:user_id>替换为<username> or <str:username>

The only thing I changed from your code is to override the get_object<\/code> method by filtering with the username instead of the default pk<\/code> .我对您的代码所做的唯一更改是通过使用用户名而不是默认的pk<\/code>过滤来覆盖get_object<\/code>方法。 I also changed the lookup_field<\/code> to a descriptive name and used ModelSerializer<\/code> and StringRelated<\/code> in the serializer.py<\/code> .我还将lookup_field<\/code>更改为描述性名称,并在serializer.py<\/code>中使用了ModelSerializer<\/code>和StringRelated<\/code> 。

models.py<\/strong>模型.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