我有三个型号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
对于 business
和location
字段到所需的值。
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/