簡體   English   中英

將選擇限制在 django rest 框架中的外鍵

[英]Limit choices to foreignkey in django rest framework

如何限制 request.user 的圖像與節點鏈接。 我希望我能做這樣的事情:

photo = models.ForeignKey(
    Image,
    limit_choices_to={'owner': username},
)

但是 request.user 而不是 username ,我不想使用本地線程。

模型.py

class Node(models.Model):
    owner = models.ForeignKey(User)
    content = models.TextField()
    photo = models.ForeignKey(Image)

class Image(models.Model):
    owner = models.ForeignKey(User)
    file = models.ImageField(upload_to=get_upload_file_name)

序列化程序.py

class ImageSerializer(serializers.ModelSerializer):
    owner = serializers.Field('owner.username')

    class Meta:
        model = Image
        fields = ('file', 'owner')

class NodeSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Node
        fields = ('content', 'photo', 'owner')

我將通過覆蓋get_serializer_class在運行時動態返回序列化器類來處理這個問題,在那里設置字段上的choices選項:

def get_serializer_class(self, ...):
    user = self.request.user
    owner_choices = ...  # However you want to restrict the choices

    class ImageSerializer(serializers.ModelSerializer):
        owner = serializers.Field('owner.username', choices=owner_choices)

        class Meta:
            model = Image
            fields = ('file', 'owner')

    return ImageSerializer

您可以創建自定義外鍵字段並在其中定義get_queryset()方法以僅將相關對象過濾為您的用戶的對象。 可以從上下文中的請求中檢索當前用戶:

class UserPhotoForeignKey(serializers.PrimaryKeyRelatedField):
    def get_queryset(self):
        return Image.objects.filter(owner=self.context['request'].user)

class NodeSerializer(serializers.HyperlinkedModelSerializer):
    photo = UserPhotoForeignKey()
    class Meta:
        model = Node
        fields = ('content', 'photo', 'owner')

此示例使用 Django REST Framework 版本 3。

class CustomForeignKey(serializers.PrimaryKeyRelatedField):
    def get_queryset(self):
        return Table.objects.filter(is_active=True)

class Serializer(serializers.ModelSerializer):
    (...)
   table= CustomForeignKey()
   class Meta:
   (...)

更簡單的是:

class Serializer(serializers.ModelSerializer):
    (...)
    table = serializers.PrimaryKeyRelatedField(queryset=Table.objects.filter(is_active=True)) 
    class Meta:
    (...)

因為我確信這個邏輯將在整個 Django 應用程序中使用,為什么不讓它更通用呢?

class YourPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):

    def __init__(self, **kwargs):
        self.model = kwargs.pop('model')
        assert hasattr(self.model, 'owner')
        super().__init__(**kwargs)


    def get_queryset(self):
        return self.model.objects.filter(owner=self.context['request'].user)

序列化程序.py

class SomeModelSerializersWithABunchOfOwners(serializers.ModelSerializer):

    photo = YourPrimaryKeyRelatedField(model=Photo)
    categories = YourPrimaryKeyRelatedField(model=Category,
                                            many=True)
    # ...

from rest_framework import serializers

class CustomForeignKey(serializers.PrimaryKeyRelatedField):
    def get_queryset(self):
        return Table.objects.filter(user=self.context['request'].user)
        # or: ...objects.filter(user=serializers.CurrentUserDefault()(self))

class Serializer(serializers.ModelSerializer):
   table = CustomForeignKey()

暫無
暫無

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

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