【问题标题】:Django custom field widget and widget behaviour for a custom "ListField"自定义“ListField”的 Django 自定义字段小部件和小部件行为
【发布时间】:2014-06-24 04:26:37
【问题描述】:

我正在创建以下基于 How to create list field in django 的自定义字段

import re

from django.db            import models
from django.forms.widgets import TextInput

class ListField(models.TextField):
    __metaclass__ = models.SubfieldBase
    description   = "Stores a python list"
    widget        = TextInput

    def __init__(self, *args, **kwargs):
        super(ListField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        if not value:
            return []

        return filter(None, re.split(r'\,|\s*', value))

    def get_prep_value(self, value):
        if value is None:
            return value

        return ', '.join(value)

    def value_to_string(self, obj):
        value = self._get_val_from_obj(obj)
        return self.get_db_prep_value(value)

from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^cflowportal\.utils\.modelutils\.ListField"])

基本上,我想要实现的是一个字段,您可以在其中编写诸如“1,asd,asdf fdgd”之类的内容,它将其存储在数据库中,但是当检索到它时,它应该将该字符串作为数组返回,并且当给定一个数组它应该将其转换回逗号分隔的字符串。

我仍然不确定到目前为止我所写的内容是否有效,但即使我设置了 widget=TextInput,我也无法将其显示为输入字段而不是文本区域。

那么,如何使用标准 CharField 使用的相同输入在管理员中显示它? 如何自定义它,以便在此类输入上显示时显示以逗号分隔的字符串,但在其他地方访问时作为 Python 列表返回?

谢谢

【问题讨论】:

  • 我之前也遇到过同样的问题,每次保存的时候都会转换。结果,内容中有许多 [ 和 ]
  • 这也是我遇到的问题
  • 它可以在 shell 或 views.py 中工作,但不能在管理站点中工作,我找不到更好的方法来解决这个问题,也许是转换函数而不是 ListField,只需使用 TextField 或 CharField ,当你阅读时,在models.py中写一个你的类的函数,例如get_content将内容转换为列表,只需使用obj.get_content()而不是obj.content......但我除了更好的答案
  • 这可能会有所帮助,gist.github.com/jonashaag/1200165

标签: django model field


【解决方案1】:

下面是实现你想要的方法

from django.db import models

class Blog(models.Model):
    title = models.CharField(max_length=256)
    labels = models.TextField()

    def get_labels(self):
        return self.content.split('\n')

    def set_labels(self,value):
        if isinstance(value,list) or isinstance(value,tuple) or isinstance(value,set):
            content = '\n'.join(value)
        else:
            content = value
        self.content = content

你可以把标签看成一个ListField,设置值使用obj.set_labels(list)函数,获取值使用obj.get_labels() 它作为一个列表字段,管理站点将作为一个普通的文本字段运行。

这就是我所做的,但更好的解决方案除外。

更好的方法是在 admin.py 中使用 save_model:

class BlogAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # extra data handling, prevent data convert
        obj.save()

【讨论】:

  • 替换 \n 使用你的分隔符
猜你喜欢
  • 2012-01-18
  • 1970-01-01
  • 2013-09-13
  • 2011-02-03
  • 2015-07-27
  • 2011-03-01
  • 1970-01-01
  • 2013-04-03
  • 2019-02-27
相关资源
最近更新 更多