python - 当 unique_together 应用于 django-rest 时,SlugRelatedField 的查询集值

标签 python json django django-rest-framework

我正在为 ESP8266 构建一个简单的 API,以便在物联网应用程序中连接,传递一个 JSON 字符串。在此应用程序中,每个站点(位置/地址)有多个监视器(互联网连接设备),每个站点/监视器有多个日志条目。

API 最初设置有如下端点: /api/logentries/

发布一个 JSON 字符串,例如: {"site":"abcd","monitor":"xyz","data_point":"value"}

在对象模型中,Monitor是Site的child,但是为了方便条目的创建和上报,各个设备发布的LogEntry的JSON格式将这个结构扁平化了,也就是说LogEntry模型也有FK关系站点和监视器。在下面的代码中,“textID”是在站点/监视器的 API 上下文中使用的 ID(例如,PK 值对 API 调用者保持“隐藏”状态)。

在 models.py 中:

class Site(models.Model):
    name = models.CharField(max_length=32)
    textID = models.CharField(max_length=32, blank=True, db_index=True, unique=True)

class Monitor(models.Model):
    textID = models.CharField(max_length=32)
    site = models.ForeignKey(Site, on_delete=models.CASCADE)

    class Meta:
        unique_together = ('site', 'textID')

class LogEntry(models.Model):
    site = models.ForeignKey(Site, on_delete=models.CASCADE)
    monitor = models.ForeignKey(Monitor, on_delete=models.CASCADE)
    data_point = models.CharField(max_length=8, default='')

为了让它在单个站点上运行,我创建了一个自定义序列化程序:

class LogEntrySerializer(serializers.HyperlinkedModelSerializer):
    site = serializers.SlugRelatedField(slug_field='textID', queryset=Site.objects.all())
    monitor = serializers.SlugRelatedField(slug_field='textID', queryset=Monitor.objects.filter())

    class Meta:
        model = LogEntry
        fields = ('pk', 'site', 'monitor', 'data_point', )

这适用于读取有效数据,并在所有监视器 ID 跨站点唯一时保存。

但是,如果两个站点的监视器具有相同的 textID——例如“Site1/001”和“Site2/001”这会中断,因为 Monitor.objects.all() 会导致检索到多个记录(这是有道理的,也是预期的行为)。

我想做的是将第二个查询集(用于监视器)限制在指定站点,以避免出现此错误。

This post几乎回答了我的问题,但是它受益于第二个字段值(用户)在请求对象中可用,这在这种情况下不可用。

有没有一种方法可以检索查询集值的 Site.pk 或 Site.textID 以正确解析——例如queryset=Monitor.objects.filter(site__textID=xxx)——“xxx”是什么?或者我是否需要完全覆盖序列化程序(而不是依赖 SlugRelatedField)?或者其他一些可能有效的方法?

(顺便说一句:我认识到这可以通过将 URL 模式修改为/api///logentries 之类的内容来实现,这样可以将此信息作为请求/上下文的一部分提供,并且从规范化的角度来看也更好。但是,这将需要重新刷新许多已部署的设备以反射(reflect)已更改的 API 详细信息,因此我想尽可能避免此类更改,即使经过反射(reflection)这可能是一个更清洁的解决方案/方法 long-术语。)

提前致谢。

最佳答案

您需要编写自己的 SlugRelatedField 子类。适用于 SlugRelatedField 的唯一性约束不适用于您的情况。 这可以通过创建子字段并覆盖 get_value 来检索站点/监视器元组和 to_internal_value 来选择适当的监视器来完成。

关于python - 当 unique_together 应用于 django-rest 时,SlugRelatedField 的查询集值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37108174/

相关文章:

python - Django "ValueErrror: could not find common ancestor of {migrations}"

Django 问题与扩展模板标签

python - Pandas:计算平均值,忽略自己行的值

python - 过滤 Flask Marshmallow 中的嵌套字段

python - 为什么在 VS Code 中单击调试测试时会收到 "TypeError: message must be set"?

Python:修改包含数组 View 的单个字典项会修改所有项

java - 在获取值之前如何对 JSONObject 中的每个元素进行 null 检查?

ios - 使用 AFNetworking 处理单个请求的多个 JSON 响应

json - mapstructure 如何使用鉴别器来解码具体类型

python - 为什么我不能用 ipython 访问 Django 的 shell 中的导入函数?