如何在 Django 中创建列表字段 [英] How to create list field in django

查看:40
本文介绍了如何在 Django 中创建列表字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 Django (Python) 中创建一个 ListField,例如 ListProperty Google App Engine (Python) 中的属性?我的数据是这样的列表:3,4,5,6,7,8.

我必须定义什么属性以及如何从中获取值?

解决方案

使用您可以使用的 ListField 类型重新审视这个问题.但它做出了一些假设,例如您没有在列表中存储复杂类型.出于这个原因,我使用 ast.literal_eval() 来强制只有简单的内置类型可以作为成员存储在 ListField 中:

from django.db 导入模型进口AST类 ListField(models.TextField):__metaclass__ = models.SubfieldBasedescription = "存储一个 python 列表"def __init__(self, *args, **kwargs):super(ListField, self).__init__(*args, **kwargs)def to_python(self, value):如果不值:价值 = []如果是实例(值,列表):返回值返回 ast.literal_eval(value)def get_prep_value(self, value):如果值为无:返回值返回 unicode(值)def value_to_string(self, obj):值 = self._get_val_from_obj(obj)返回 self.get_db_prep_value(value)类虚拟(模型.模型):mylist = ListField()

试一试:

<预><代码>>>>from foo.models import Dummy, ListField>>>d = 虚拟()>>>d.mylist[]>>>d.mylist = [3,4,5,6,7,8]>>>d.mylist[3, 4, 5, 6, 7, 8]>>>f = ListField()>>>f.get_prep_value(d.numbers)你'[3, 4, 5, 6, 7, 8]'

你知道一个列表作为 unicode 字符串存储在数据库中,当它被拉出时,它会通过 ast.literal_eval().

以前我从这篇关于 自定义字段的博客文章中提出了这个解决方案姜戈:

<块引用>

CommaSeparatedIntegerField 的替代方案,它允许您存储任何分隔值.您还可以选择指定令牌参数.

from django.db 导入模型类SeparatedValuesField(models.TextField):__metaclass__ = models.SubfieldBasedef __init__(self, *args, **kwargs):self.token = kwargs.pop('token', ',')super(SeparatedValuesField, self).__init__(*args, **kwargs)def to_python(self, value):如果不是值:返回如果是实例(值,列表):返回值返回值.split(self.token)def get_db_prep_value(self, value):如果不是值:返回断言(isinstance(值,列表)或isinstance(值,元组))return self.token.join([unicode(s) for s in value])def value_to_string(self, obj):值 = self._get_val_from_obj(obj)返回 self.get_db_prep_value(value)

How do I create a ListField in Django (Python) like the ListProperty property in Google App Engine (Python)? My data is a list like this : 3,4,5,6,7,8.

What property do I have to define and how would I fetch values from it?

解决方案

Revisiting this with a ListField type you can use. But it makes a few of assumptions, such as the fact that you're not storing complex types in your list. For this reason I used ast.literal_eval() to enforce that only simple, built-in types can be stored as members in a ListField:

from django.db import models
import ast

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

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

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

        if isinstance(value, list):
            return value

        return ast.literal_eval(value)

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

        return unicode(value)

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

class Dummy(models.Model):
    mylist = ListField()

Taking it for a spin:

>>> from foo.models import Dummy, ListField
>>> d = Dummy()
>>> d.mylist
[]
>>> d.mylist = [3,4,5,6,7,8]
>>> d.mylist
[3, 4, 5, 6, 7, 8]
>>> f = ListField()
>>> f.get_prep_value(d.numbers)
u'[3, 4, 5, 6, 7, 8]'

There you have it that a list is stored in the database as a unicode string, and when pulled back out it is run through ast.literal_eval().

Previously I suggested this solution from this blog post about Custom Fields in Django:

An alternative to the CommaSeparatedIntegerField, it allows you to store any separated values. You can also optionally specify a token parameter.

from django.db import models

class SeparatedValuesField(models.TextField):
    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        self.token = kwargs.pop('token', ',')
        super(SeparatedValuesField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        if not value: return
        if isinstance(value, list):
            return value
        return value.split(self.token)

    def get_db_prep_value(self, value):
        if not value: return
        assert(isinstance(value, list) or isinstance(value, tuple))
        return self.token.join([unicode(s) for s in value])

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

这篇关于如何在 Django 中创建列表字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆