【问题标题】:django model choices make no effect on saved datadjango 模型选择对保存的数据没有影响
【发布时间】:2015-05-06 23:59:54
【问题描述】:

按照django documentation,我尝试在我的 models.py:

class MyModel(Model):

    ACTION_CHOICES = (
        ('d', 'delete'),
        ('c', 'create'),
        ('u', 'update'),
    )

    action = CharField(max_length=1, choices=ACTION_CHOICES)

但是当我运行它时

 action = MyModel(action='create')
 action.save()

并检查数据库操作不是c,而是create。此外,即使对 max_length 的限制也不会影响它。好的,我继续前进并尝试以这种方式进行:

models.py

class MyModel(Model):

    ACTION_CHOICES = (
        (1, 'delete'),
        (2, 'create'),
        (3, 'update'),
    )

    action = IntegerField(max_length=1, choices=ACTION_CHOICES)

code.py:

action = MyModel(action='create')
action.save()

但我得到一个错误,即 str 字段无法像 int 一样保存(数据库有 int 字段,但 MyModel.action 是 str)我在这里错过了什么?选择不应该在保存时转换价值吗?

最好的问候,

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    您的帖子中有几个问题:

    1) choices 只能限制可以通过 Django 表单输入的内容。当您手动实例化您的对象时,您可以插入任何值。所以

    action = MyModel(action='create')
    

    实际上是将字符串create 插入到操作列中。

    2) 通常max_length 应该阻止您将长度超过 1 个字符的字符串插入该列,但我猜您使用的是具有no restriction on VARCHAR lengths 的 SQLite。

    3) Django 没有简单的从显示值到选择键的转换。您可以查看 django-model-utils 以了解有关选择的包装。

    【讨论】:

    • 我已经以这种方式使用过它,并且我有 110% 的把握它应该可以解决问题。这是code,其中变量sex 设置为“女性”。变量profile 是UserProfile 的实例。 Here 是它的型号。数据库值是布尔值。我刚刚检查过了。 here 它不起作用。我就是这么盲目,找不到区别。
    • 我不知道该代码,但有可能您将每个人都插入为“男性”,因为任何非空字符串都等效于布尔值 True。
    【解决方案2】:

    当你定义选择时

    ACTION_CHOICES = (
        (1, 'delete'),
        (2, 'create'),
        (3, 'update'),
    )
    

    存储在db中的值是1、2、3,而'delete'、'create'等只是标签,只是为了解释一下,prev选择导致这样的选择输入元素:

    <select>
        <option value="1">delete</option>
        <option value="2">create</option>
        <option value="3">update</option>
    </select>
    

    选项不应该在保存时转换值,应该用标签映射 db 值,并在呈现表单小部件和检索字段表示 (get_field_display) 时使用。但是如果你直接设置列的值,它就不起作用了。

    如果你想使用“说话的钥匙”,你可以将它们定义为类属性,比如

    class MyModel(models.Model):
        DELETE_ACTION = 1
        CREATE_ACTION = 2
        UPDATE_ACTION = 3
    
        ACTION_CHOICES = (
            (DELETE_ACTION, 'delete'),
            (CREATE_ACTION, 'create'),
            (UPDATE_ACTION, 'update'),
        )
    

    那你就可以了

    action = MyModel(action=MyModel.CREATE_ACTION)
    

    这样就好了

    【讨论】:

    • 没错,这就是我想要达到的目标,我希望将值 1 2 3 存储在数据库中。我将标签设置为delete,我希望它在数据库中,如1。但我看到的是delete。
    • 但是您直接设置字段:action = MyModel(action='create'),如果您以这种方式设置列,则必须尊重列类型,渲染时使用选择元组表单小部件或检索“文本”值,而不是直接设置字段值
    • 那么如何设置标签呢?我不想知道它应该存储在数据库中。那是什么元组转换。我将标签设置为“删除”,元组将其转换为 django 数据库层上的1。这不就是选择的目的吗?
    • 是的,当您通过表单和选择小部件插入值时,而不是直接设置列值时,因为毕竟列类型是整数
    • 你能不能看看我的comment,点击后刷新页面。
    猜你喜欢
    • 2014-04-18
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    相关资源
    最近更新 更多