【发布时间】:2017-10-22 01:01:28
【问题描述】:
我对 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 固定装置预先填充的查找表。用户可以选择一个基本原理来给出警报打开的原因。基本原理是可选的,因此可以为空。
但是,当我尝试将 Rationale 设置为 None 时出现错误:
{'rationale': [u'类型不正确。预期的 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=True 或查询集。但是它没有提供如何做到这一点的示例,我无法弄清楚或在任何地方找到任何示例。
我需要涵盖以下两种情况:
data = {'alert' : 1, 'priority' : 2, reasone: 1 } 将基本原理设置为基本原理 1 的外键。
还有:
data = {'alert' : 1, 'priority' : 2,rational: None } 如果用户想要将理由设置为空。当他们只是在没有选择理由的情况下更新优先级时,这种用例更有可能发生。
所以我尝试将我的查询集定义为“全部”
rationale = serializers.PrimaryKeyRelatedField(queryset=Rationale.objects.all(), allow_null=True)
但这会导致我的所有基本原理为 None 的测试都给出原始异常:
{'rationale': [u'类型不正确。预期的 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。
如何正确定义我的查询集?
谢谢。
【问题讨论】:
-
你想让这个序列化程序从对象中获取数据并更新数据,不是吗?
-
是的。我们需要能够查询历史表,以便我们可以显示随时间的变化。因此,在 /alerts/history 的获取将返回表格的内容,而对 /alerts/history 的帖子将让他们更改值。