【问题标题】:Django - Modify field value after every queryDjango - 每次查询后修改字段值
【发布时间】:2019-01-03 06:04:54
【问题描述】:

我对来自 Laravel 背景的 Django 相当陌生。我想在每次查询时修改一个字段值。例如,每次查询 firstname@User 时,都会返回大写的名字。在 Laravel 中这被称为 Accessors 但显然访问器在 Django 中具有不同的含义。就我而言,我有一个名为 Meta 的键值表,其中 value 字段可以是任何类型:

class Meta(models.Model):
    key = models.CharField(max_length=30)
    value = models.TextField()
    model = models.ForeignKey('Model', on_delete=models.CASCADE)

在获得值Meta.objects.get(key='foo') 后,我想返回ast.literal_eval(value) 以将字符串表达式转换为正确的相应类型。我做了一些研究,只发现以下内容:

  • 创建自定义字段。
  • 使用 get_foo_display(self),但据我所知,这只适用于 ChoiceField。

每次我查询value 过滤时应用此功能的最佳选择是什么key

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    您可以使用自定义字段,但这里最简单的方法是使用属性。

    class Meta(models.Model):
        value = models.TextField()
    
        @property
        def converted_value(self):
            return ast.literal_eval(self.value) 
    

    现在您可以在需要转换后的值时访问my_meta.converted_value

    【讨论】:

    • 工作就像一个魅力。我知道这很容易实现,但我在文档中找不到它。我不知道我是如何从文档中错过它的。非常感谢
    • 这是一个通用的 Python 东西,所以没有在 Django 文档中专门介绍。不要忘记接受答案,以向未来的搜索者表明它对您有所帮助。
    【解决方案2】:

    @property 是一个不错的方法,但是如果您将访问大量时间 ast.literal_eval 并且处理成本很高,则可以覆盖 save 方法:

    def __init__(self, *args, **kwargs):                                         
        super(Meta, self).__init__(*args, **kwargs)                         
        self.__original_value = self.value
    
    def save(self, **kwargs):
        if self.__original_value != self.value:
            self.value = ast.literal_eval(self.value)
        super(Meta, self).save()
    

    init 会选择更新前的值

    【讨论】:

    • 性能明智,您的方法更好,但您忘记在 init 中添加逻辑我认为.. 应该有 self.converted_value = ast.literal_eval(self.value) 然后在 save 函数中,如果他们不匹配则converted_value = ast.literal_eval(self.value)。感谢您的方法,一旦修复,我会选择您的答案,因为它具有更好的性能
    • 嗨,通常__init__ 中的self.value 是旧值(在save() 之前),因此它已经与ast.literal_eval 一起保存在数据库中
    猜你喜欢
    • 1970-01-01
    • 2021-09-23
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 2015-11-07
    • 2014-11-11
    • 2017-08-05
    相关资源
    最近更新 更多