Django,MySQL和JSONField的过滤问题

时间:2019-11-26 16:36:10

标签: json django django-models django-rest-framework

我正在解决在Django内部过滤模型的问题。我还将django_mysql JSONField字段类型用于我的模态内字段的所有“类别”。


class Image(models.Model):
    class Meta:
        verbose_name = "Image"
        verbose_name_plural = "Images"

    image = models.ImageField(verbose_name="Image Asset", upload_to='assets/images/', blank=True, null=True)
    is_published = models.BooleanField(verbose_name="Is this asset published", default=True, null=False)
    meta_format = models.CharField(verbose_name="Meta Format", max_length=200, blank=True, null=True)
    meta_width = models.CharField(verbose_name="Meta Width", max_length=200, blank=True, null=True)
    meta_height = models.CharField(verbose_name="Meta Height", max_length=200, blank=True, null=True)
    categories = JSONField(default=list)

作为参考,类别是我尝试过滤的字段。

让我们说我的供稿中有此条目:

{
    "id": 18,
    "url": "http://localhost:8001/images/18/",
    "image": "https://cdn.test.com/assets/images/person.jpg",
    "is_published": false,
    "meta_format": "JPEG",
    "meta_width": "1466",
    "meta_height": "800",
    "categories": "[{\"category\": \"staff_gallery\"}]"
}

唯一会返回此结果的是

>>> ImageAsset.objects.filter(categories="[{\"category\": \"staff_gallery\"}]")

这是不可行的,因为很可能会有不止一个类别。如果条目更改为"categories": "[{\"category\": \"staff_gallery\"},{\"category\": \"test\"}]",则整个查询将不返回任何内容。

解决这个问题的一种方法是将其变成一个列表或数组...因此,基本上上述类别将变为"categories": "[\"staff_gallery\"]"。这样,以下查询将起作用并返回我想要的查询。

>>> ImageAsset.objects.filter(categories__contains="[\"staff_gallery\"]")

但是...当我将条目更改为"categories": "[\"staff_gallery\",\"test\"]"时,查询将停止工作,除非我在查询内部完全指定了该字符串("[\"staff_gallery\",\"test\"]")。

这个category字段最初是一个数据字段,我在其中存储的不仅仅是这个数据字段,但是鉴于我遇到的问题,我已经将其转换为category字段。我的问题是,如果无法弄清楚,我将其切换为char字段,然后在其中搜索。我以为这些JSON字段应该是未来的更易使用的方式...但是我发现情况并非如此。

TL; DR:过滤(如文档所述)不起作用。 JSON文件过滤除了对字段内容的完全匹配之外没有任何作用。

1 个答案:

答案 0 :(得分:0)

JSONField documentation中所述,存在用于查询JSONField的特定查找。

例如,如果要获取“ staff_gallery”类别的图像,则必须使用以下内容:

ImageAsset.objects.filter(categories={'category': 'staff_gallery'})

查看上面的链接以获取更多详细信息。