【问题标题】:How to update the field of django model from the existing field on the Fly如何即时从现有字段更新 django 模型的字段
【发布时间】:2020-03-16 17:16:07
【问题描述】:

如何通过taking/extracting values or filtering values从同一对象的现有字段中更新django模型的字段?

我有以下型号:

from django.contrib.postgres.fields import JSONField,ArrayField

class MyUrlModel(models.Model):
    urls_json_data = JSONField(blank=True,null=True,default=dict)
    urls_list = ArrayField(models.TextField(blank=True),blank=True,null=True,default=list)

字段urls_json_data在json中有如下数据:

[{"protocol":"http","hostname":"google.com","port":80"},{"protocol":"https","hostname":"apple.com","port":443"}]

在这里,我想从urls_json_data 获取结构并将其制成如下所示的url 结构并将它们保存在urls_list 下,即ArrayField。

urls_list=['http://google.com:80','https://apple.com:443']

所以每当urls_json_data 得到更新时,我想从中获取URL 并将其保存在urls_list 下。最好的方法是什么,是通过信号还是通过改变保存方法?

urls_list = []
for each_data in urls_json_data:
  url = each_data['protocol']+each_data['hostname']+each_data['port']
  urls_list.append(url)

【问题讨论】:

  • 有什么理由必须先保存 json 吗?保存之前可以不把json转成url吗?
  • 这就是我现在正在做的事情,我想知道当urls_json_data 字段被更新/创建时是否还有其他解决方法可以即时完成。

标签: django django-models django-rest-framework django-forms django-templates


【解决方案1】:

一般来说,每当您发现自己处于一个字段依赖于另一个字段的值的情况下,大多数时候最好将依赖字段设置为属性,例如使用property 描述符。

在您的情况下,您应该urls_list 设为property

class MyUrlModel(models.Model):
    urls_json_data = JSONField(blank=True,null=True,default=dict)

    @property
    def urls_list(self):
        # Parse `self.urls_json_data` and return

现在从模型的任何实例中,您都可以通过<instance>.urls_list 引用该值。

如果您认为urls_list 的计算量很大,那么您可以将其作为一种方法,例如get_urls_list 以确保用户不会认为 urls_list便宜 字段访问。


如果你坚持使用urls_list作为一个依赖于urls_json_data当前值的字段,你可以覆盖模型的save方法并在保存字段之前在那里进行操作例如:

class MyUrlModel(models.Model):
    urls_json_data = JSONField()
    urls_list = ArrayField()

    def save(self, *args, **kwargs):
        # `self.get_from_urls_json_field()` is a placeholder
        # for the actual operations to be done
        self.urls_list = self.get_from_urls_json_field()
        super().save(*args, **kwargs)

【讨论】:

  • 这是一个不错的装饰器和一个好方法,但小缺点是当我们有很大的urls_json_data & 每次我调用该对象时它都会加载属性,有什么办法可以保存它一个领域?这样它就可以快速完成。
  • 是否可以更新其他模型字段的字段而不是相同的模型字段?
  • @ArbazzHussain 是的,您需要从该模型中获取对象(请参阅Queryset.get/QuerySet.filter),然后进行更新。
【解决方案2】:

您甚至可能不需要存储数据,您可以添加一个动态返回 URL 的属性

class MyUrlModel(models.Model):
    urls_json_data = JSONField(blank=True,null=True,default=dict)

    @property
    def urls_list(self):
        return ['{protocol}{hostname}{port}'.format(**url) for url in self.urls_json_data]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 2017-12-28
    • 2020-08-13
    • 1970-01-01
    • 2020-01-26
    • 2020-02-13
    相关资源
    最近更新 更多