【问题标题】:Is it possible to use model's @property decorators with Model.values()?是否可以将模型的 @property 装饰器与 Model.values() 一起使用?
【发布时间】:2017-08-24 13:00:46
【问题描述】:

我有一个包含以下字段和装饰器的模型:

class Item(models.Model):

    title = models.CharField(db_index=True, max_length=100)
    thumb = models.CharField(max_length=1000)
    vendor = models.CharField(max_length=15)
    url = models.CharField(max_length=255, unique=True)
    views = models.CharField(max_length=64)

    @property
    def parsed_thumb()
        return = self.url + "/static/" + self.thumb

我在基于类的视图中查询:

results = Items.objects.filter(title__icontains=query).order_by('-views')[offset:limit].values('id', 'url', 'title', 'vendor', 'thumb')

问题是对 values() 的调用返回 db 字段,据我所知,无法与属于 Items 模型的 @property 装饰器进行交互。

我需要来自parsed_thumb() 的返回值。我有哪些选择?

【问题讨论】:

  • 您确定需要使用values()吗?为什么不使用常规查询集并访问该属性?

标签: python django django-models


【解决方案1】:

查询集用于与数据库交互,其中属性只能由模型访问。您可以使用 Concat 注释该属性以使用查询集,但这不会使用该属性

results = Items.objects.filter(title__icontains=query).order_by('-views')
results = results.annotate(parsed_thumb=Concat('url', Value('/static/'), 'thumb'))[offset:limit].values('id', 'url', 'title', 'vendor', 'thumb', 'parsed_thumb')

【讨论】:

  • 我喜欢这个解决方案,它适用于我遇到的问题,所以我将其标记为正确。不幸的是,我简化了这个问题,所以我可以很容易地解释它。我还有其他字段需要从二进制转换为十进制,以及其他修改。我很快尝试扩展您的答案以解决我的其他问题,例如:results = results.annotate(dec_num=self.bin_to_dec(bin_field)) 但看起来我只能使用您提供的链接中的 Django 数据库函数。不过,感谢您为我提出的问题提供了一个很好的答案。
  • @Sam - 你可能会遇到困难(见Django custom annotation function)。此处的答案建议使用 extra,但在 django 文档中对使用 extra 有很大的警告。
  • 是的,我越是关注这个问题,就越意识到它会变得多么混乱。出于显而易见的原因,我真的不想使用extra()
【解决方案2】:

如果你有这么简单的方法可以试试QuerySet.extra

results = Items.objects.extra(
    select={'parsed_thumb': "url || '/static/' || thumb"}
).filter(title__icontains=query).order_by('-views')[offset:limit].values(
'id', 'url', 'title', 'vendor', 'thumb', 'parsed_thumb') 

【讨论】:

    猜你喜欢
    • 2020-02-03
    • 2015-10-10
    • 2018-04-14
    • 2022-11-29
    • 2012-12-17
    • 1970-01-01
    • 2012-10-31
    • 2013-02-27
    • 1970-01-01
    相关资源
    最近更新 更多