python - Django Rest Framework中如何根据一些请求参数限制序列化器相关字段的查询集

标签 python django django-rest-framework

我有三个型号Transaction , Business ,和Location 。它们的定义如下:

class Business(models.Model): 
    # Can have zero or more locations. A user can have many businesses.
    name  = models.CharField(max_length=200, validators=[MinLengthValidator(1)])
    # ... and some other fields ...

class Location(models.Model): 
    # Must have one business. Locations cannot exist without a business
    suburb   = models.CharField(max_length=150, validators=[MinLengthValidator(1)])
    business = models.ForeignKey(Business, related_name='locations')
    # ... and some other fields ...

class Transaction(models.Model): 
    # Can have zero or one business
    # Can have zero or one location and the location must belong to the business. If business is empty, location must be empty
    business = models.ForeignKey(Business, on_delete=models.SET_NULL, null=True, blank=True, related_name='transactions')
    location = models.ForeignKey(Location, on_delete=models.SET_NULL, null=True, blank=True, related_name='transactions')
    # ... and some other fields ...

和序列化器:

class BusinessRelatedField(serializers.PrimaryKeyRelatedField):

    def get_queryset(self):
        owner = get_owner_from_context(self.context)
        return Business.objects.filter(owner=owner)

class LocationRelatedField(serializers.PrimaryKeyRelatedField):

    def get_queryset(self):
        params = self.context['request'].query_params
        business_params = params.get('business')
        if business_params is not None:
            owner = get_owner_from_context(self.context)
            return Location.objects.filter(owner=owner, business=business_params)
        else:
            return None

class TransactionSerializer(serializers.ModelSerializer):

    business = BusinessRelatedField(required=False, allow_null=True)
    location = LocationRelatedField(required=False, allow_null=True)

我面临的问题是我不知道如何限制 Location 的值基于 Business 的值。我在 TransactionSerializer 内手动执行此检查的validate方法,直到我想到创建一个 PrimaryKeyRelatedField子类化并覆盖 get_queryset方法。这对我来说似乎是一个更好的方法(而且它实际上有效),但我想知道这是否是“正常”的做法。

我现在面临的另一个问题是“可浏览的 API”不再显示 Location 的任何选择我觉得这暗示我可能做错了什么。

如有任何帮助,我们将不胜感激。

最佳答案

您可以覆盖 get_fields()序列化器的方法并修改 queryset对于 businesslocation字段到所需的值。

get_fields()序列化器使用方法来生成 field names -> field instances映射时.fields可以在其上访问属性。

class TransactionSerializer(serializers.ModelSerializer):

    class Meta:
        model = Transaction
        fields = (.., business, transaction)

    def get_fields(self):
        # get the original field names to field instances mapping
        fields = super(TransactionSerializer, self).get_fields()

        # get the required parameters
        owner = get_owner_from_context(self.context)
        business_params = self.context['request'].query_params.get('business')

        # modify the queryset
        fields['business'].queryset = Business.objects.filter(owner=owner)
        fields['location'].queryset = Location.objects.filter(owner=owner, business=business_params)

        # return the modified fields mapping
        return fields

关于python - Django Rest Framework中如何根据一些请求参数限制序列化器相关字段的查询集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37614840/

相关文章:

python - Django Rest Framework 3 : Uploading files without request. 文件

python - 无法在 Keras 的 ImageDataGenerator 中将 preprocess_input 用作预处理函数

Python 命令行 : editing mistake on previous line?

Django REST Framework ManyToMany 过滤多个值

python - 在 Django 中的 form.cleaned_data[i] 上使用 rstrip

django - 从 Django Rest Framework SIMPLE JWT token (第 3 方)获取中间件中的用户名

python - 转换连接到 XBee 的温度传感器的读数

python - Pandas 到 Excel(合并标题列)

python - 我怎样才能在 python 中解决这个分页器问题

angularjs - 用户在 Django Rest Framework 中按 session 注销