我对Python和Django都很陌生,而且我遇到了可以为空的外键关系的问题。我发现了类似的问题,但它们似乎都没有覆盖我的用例。
我正在使用Django 1.8.17和DRF 3.1.0
我在Django中有以下类(我已将它们简化为相关字段,因为我无法在此处轻松复制/粘贴代码):
class Rationale(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
class Alert(models.Model):
id = models.AutoField(primary_key=True)
rationale = models.ForeignKey(Rationale, null=True, blank=True)
priority = models.IntegerField(default=1)
class AlertHistory(models.Model):
id = models.AutoField(primary_key=True)
alert = = models.ForeignKey(Alert)
rationale = models.ForeignKey(Rationale, null=True, blank=True)
priority = models.IntegerField(null=True)
class AlertHistoryListView(generics.ListCreateAPIView):
queryset = AlertHistory.objects.all()
serializer_class = AlertHistorySerializer
pagination_class = DefaultPagination
filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter)
filter_class = AlertHistoryFilterSet
filter_fields = ['alert']
ordering_fields = filter_fields
class AlertHistoryFilterSet(django_filters.FilterSet):
class Meta:
model = AlertHistory
fields = ['alert']
这里的想法是捕获历史记录表中警报的更改。用户可以更新优先级或基本原理。
Rationale表是预先填充了JSON fixture的查找。用户可以选择基本原理来说明警报打开的原因。基本原理是可选的,因此可以为空。
但是当我尝试将基本原理设置为无时出现错误:
{'理由':[你不正确的类型。预期的pk值,收到unicode。']}
所以四处寻找导致我:PrimaryKeyRelatedField:http://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield
然后我更新了我的AlertHistory序列化程序:
class AlertHistorySerializer(serializers.ModelSerializer):
rationale = serializers.PrimaryKeyRelatedField(read_only=True, allow_null=True)
class Meta:
model = AlertHistory
这解决了我的第一个问题,但导致我在更新基本原理的测试中遇到问题。通过将其标记为read_only,我毫不奇怪地无法更新该字段。
文档说我需要指定read_only = True或查询集。然而,它没有提供如何做到这一点的例子,我无法弄明白或在任何地方找到任何例子。
我需要涵盖以下两种情况:
data = {'alert':1,'priority':2,reasonale:1}为基本原理1设置外键的基本原理。
和
data = {'alert':1,'priority':2,reasonale:None}如果用户想要将基本原理设置为null。当用户只是在不选择基本原理的情况下更新优先级时,更有可能使用此用例。
所以我尝试将我的查询集定义为“all”
rationale = serializers.PrimaryKeyRelatedField(queryset=Rationale.objects.all(), allow_null=True)
但是这导致我的所有测试,其中基本原理是无,以给出原始异常:
{'理由':[你不正确的类型。预期的pk值,接收到unicode。']},即使我现在将allow_null设置为True。
然后我尝试定义:
rationale = serializers.PrimaryKeyRelatedField(queryset=Rationale.objects.get(pk=rationale), allow_null=True)
但它不知道是什么原因。
我也尝试过:
rationale = serializers.PrimaryKeyRelatedField(source='rationale', allow_null=True)
但这导致了我的错误:
AssertionError:关系字段必须提供'queryset'参数,或设置read_only = True
。
如何正确定义查询集?
感谢。
答案 0 :(得分:0)
使用此序列化程序:
class AlertHistorySerializer(serializers.ModelSerializer):
class Meta:
model = AlertHistory
模型:
class AlertHistory(models.Model):
id = models.AutoField(primary_key=True)
alert = = models.ForeignKey(Alert)
rationale = models.ForeignKey(Rationale, null=True)
priority = models.IntegerField(null=True)
用于创建警报历史记录对象的示例json:
{
"alert": 1,
"rationale": null,
"priority": 2
}
如果你想在json
中将基本原理设置为null发送null
PS:确保更新了数据库架构,并且已应用了所有迁移。