【问题标题】:CharField(editable=False) with local variable as deaultCharField(editable=False) 默认为局部变量
【发布时间】:2019-11-19 03:16:55
【问题描述】:

我是 django 新手,正在尝试弄清楚如何将特定字段添加到 django 模型中。我想上传一个 csv 文档并保存它的标题。如您所见,我想使用随文档一起发送的标题,或者如果它们未发送,则使用文档第一行中的标题。

from django.db import models

class CSV_API_DB(models.Model):
    headers = models.CharField(max_length=250, blank=True)
    delimiter = models.CharField(max_length=1, default=';')
    filefield = models.FileField(upload_to='uploads/', max_length=100, default='empty')

    actual_headers = ''

    def __str__(self):
        actual_headers = ''

        if not self.headers:
            file_path = str(self.filefield)
            file = open(file_path)
            for line in file:
                string_line = str(line[:-1])
                actual_headers = string_line.split(self.delimiter)
                break

        else:
            actual_headers = self.headers.split(self.delimiter)
        return str(actual_headers)


    true_headers = models.CharField(max_length=250, default = str(actual_headers), editable=False)

问题似乎是,true_headers 不会被 '__ str __' 函数覆盖,因为数据库中 true_headers 的值始终只是空字符串。

【问题讨论】:

  • 快速提示:最好使用上下文管理器更安全地打开文件(以确保在发生错误时不会有未关闭的文件描述符)。阅读上下文管理器和“with open(filename) as f”
  • 我将阅读有关上下文管理器的信息,谢谢您的提示。

标签: python django default


【解决方案1】:

default 参数在迁移过程中被调用,但不是在您创建新对象时。要提供动态默认值,您应该将可调用对象传递给 default= arg。

所以要提供动态默认值,您需要传递一个返回它的函数,而不仅仅是字符串。 像这样:

...
    some_field = fields.CharField(max_length=10, default=get_some_field)  # note that no () after function name

def get_some_field():
    return some_dynamic_value

但请注意,您无法从被调用函数访问模型实例,因此如果可能,您必须使用YourModel.objects.get(...) 搜索它,或者仅使用其他方式设置动态值。例如,您可以覆盖 save() 方法:

class CSV_API_DB(models.Model):
    ...
    def save(self, *args, **kwargs):
         if not self.true_headers and self._state.adding:  # _state.adding indicates that object is being created (not just edited), so we have to set default value if none provided
             self.true_headers = self.headers.split(self.delimiter)
         super().save(*args, **kwargs)

【讨论】:

  • 我会在接下来的几天内尝试一下,感谢您的快速回答。我会报告,当我得到它的工作。
  • 你有结果了吗?
  • 嘿,抱歉现在才回答。我正在尝试并实际上制作了一个不同的线程并使用了其他人提供的解决方案。不过,我仍然感谢您的帮助。这是链接(stackoverflow.com/questions/59181875/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-19
  • 2018-05-22
  • 1970-01-01
相关资源
最近更新 更多