Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在django中创建列表字段_Python_Django_Google App Engine - Fatal编程技术网

Python 如何在django中创建列表字段

Python 如何在django中创建列表字段,python,django,google-app-engine,Python,Django,Google App Engine,如何在Django(Python)中创建一个类似于Google App Engine(Python)中的属性的列表字段?我的数据是这样的列表:3,4,5,6,7,8 我必须定义什么属性以及如何从中获取值?尝试使用CommaSeparatedIntegerField,该字段记录在此处:我执行以下操作: def get_comma_field(self, field): data = getattr(self, field) if data: return data.

如何在Django(Python)中创建一个类似于Google App Engine(Python)中的属性的列表字段?我的数据是这样的列表:
3,4,5,6,7,8


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

尝试使用
CommaSeparatedIntegerField
,该字段记录在此处:

我执行以下操作:

def get_comma_field(self, field):
    data = getattr(self, field)
    if data:
        return data.split(',')
    return []


def set_comma_field(self, val, field):
    if isinstance(val, types.StringTypes):
        setattr(self, field, val)
    else:
        setattr(self, field, ','.join(val))


def make_comma_field(field):
    def getter(self):
        return get_comma_field(self, field)

    def setter(self, val):
        return set_comma_field(self, val, field)

    return property(getter, setter)

class MyModel(models.Model):
    _myfield = models.CharField(max_length=31)
    myfield = make_comma_field('_myfield')

但我想现在可能有点过分了。我需要很多,这就是我编写make_comma_field函数的原因。

使用您可以使用的
ListField
类型重新讨论这个问题。但它做出了一些假设,例如您没有在列表中存储复杂类型。出于这个原因,我使用了
ast.literal\u eval()
来强制执行只有简单的内置类型才能作为成员存储在
列表字段中

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()
试一试:

>>> 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]'
在这里,一个列表以unicode字符串的形式存储在数据库中,当被拉出时,它将被执行

在此之前,我在这篇博客文章中提出了以下解决方案:

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


虽然jathanism的答案很好,但在尝试使用
dumpdata
命令时,我遇到了以下错误:

Error: Unable to serialize database: get_db_prep_value() takes at least 3 arguments (2 given)
问题是
self.get\u db\u prep\u value
调用
value\u to\u string
方法需要提供一个
连接
值(至少在中,这是我正在使用的)。最后,我没有真正看到通过首先调用
value\u to\u string
方法并删除它以及不必要的
\uuuu init\uuu
方法所获得的效果。这就是我的结局:

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

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

        if isinstance(value, list):
            return value

        converted = ast.literal_eval(value)
        if not isinstance(converted, list):
            raise ValueError('Value "%s" not a list' % converted)

        return converted
考虑到这一点,优势在于:

  • 保存并加载本机列表对象,无需转换
  • 经过充分测试和成熟的解决方案
  • 在您的项目中可能有其他优势
  • 支持对数据库和正则表达式进行筛选(如果需要)
此外:

  • 跨数据库支持
  • 支持Python2.7到Python3.4和Django 1.4到1.8
  • 很简单:)

如果您使用的是postgresql,django支持postgres with。

简单地说,您可以将列表存储为字符串,使用它时,使用ast.literal\u eval()首先从字符串转换为列表。例如:

import ast

class MyModel(models.Model):
    field_1 = models.any kind of field()
    list_field = models.CharField(max_length=255)

    def get_list(self):
        list = ast.literal_eval(self.list_field)
        return list
在视图等中也是如此。 保存时,对列表进行操作,最后通过以下方式将其转换为字符串:

model.list_field = str(list)
model.save()

你能给我们看一下为CommaseOperatedIntegraterField获取单个值的代码吗?如果你的数据在列表中,比如说
[3,4,5]
,那么你会像这样分配给
CommaseOperatedIntegraterField
my_object.my_field=“,”。join([str(x)for x in my_list])
应用引擎本机支持列表;以逗号分隔的方式存储列表似乎是个糟糕的主意。我是应用程序引擎团队的成员,我知道它如何存储列表:作为一系列字段。尼克,我很想看看你的替代方案,在那之前,贾塔尼主义的分离价值场方法对我的GAE Django Norel项目非常有效。谢谢。@NickJohnson你说的“本机”是什么意思?当然你不是说它在关系数据库中被规范化了。我希望GAE使用文档驱动的东西。Django(1.5.2)Field对象在get\u db\u prep\u value()方法上请求一个“connection”参数。但根本不用它?我现在明白你的意思了。你对这个问题的理解与我不同。我问这个问题是为了回答“如何在Django中创建ListField?”(列表字段类似于应用程序引擎)。它与SeparatedValuesField类几乎相同,只是不是字段类,也没有可配置的分隔符。从功能上讲,是的,但我的意思是,只要在Django框架内设置了以下约定,您所要做的就是将该方法更改为:def get_db_prep_value(self、value、connection、prepared=False)作为该方法的签名changed@OritK:怎么做?实现
ListField
的正确方法是什么?如何避免这个
get\u db\u prep\u值的问题?您的评论模棱两可:@jathanism的实现并没有定义
get\u db\u prep\u值
——只是在没有
连接
参数的地方使用它。必须承认,我不是100%确定我记得它。。但根据我的评论:您应该更改jathanism对ListField的实现。将“def get_prep_value(self,value)”改为“def get_db_prep_value(self,value,connection,prepared=False)”,它应该可以工作。我同意@OritK,这是使@jathanim的实现工作所需的最小更改。不过,我认为在该实现中有一些不必要的更改,所以除了我认为创建
ListField
model.list_field = str(list)
model.save()