我有一个长整数列表要赋值给django模型的charfield,长整数列表被转换为unicode列表

1 投票
2 回答
634 浏览
提问于 2025-04-18 13:21

我有一个长整型数字的列表,我把它们赋值给一个Django模型中的字符字段(CharField)。

这个长整型数字的列表会被转换成Unicode字符串的列表。

other_parents = models.CharField(max_length=300, blank=True)

final_list = [1L, 2L, 11L, 84L]
self.parent_list = final_list
print self.parent_list

打印出来是 [u'1', u'2', u'11', u'84']

我们能不能把它保持为长整型数字的列表呢?

2 个回答

0

Django可以自动处理你把长整型列表存储到数据库中的事情,你不需要做任何额外的工作。你不需要自定义字段;CharField会把列表用bytes()转换,然后再转成UTF8格式,最后存进数据库。你的列表可以包含字符串、数字、元组、列表、字典、布尔值和None,或者这些类型的组合。

你遇到的问题是,当你从数据库中取出这个列表时,它会变成一个unicode字符串,而不是Python列表。没关系,只要你限制数据类型在上面提到的那些,你可以使用ast.literal_eval()来安全地把字符串转换回列表:

your_app/models.py中:

from django.db import models

class List(models.Model):
    the_list = models.CharField(max_length=300, blank=True)

然后在python manage.py shell中:

>>> import ast
>>> from your_app.models import List

>>> original_list = [1, 2, 3, 444L, 1100L, -1234, 11.72, 'hi there', u'\u3030\u3000', {'a': 1, 'b': 2, 'c': [1, 2, 3]}, ('this', 'is', 'a', 'tuple'), True, None]
>>> List(the_list=original_list).save()
>>> retrieved_list = List.objects.last()
>>> retrieved_list
u"[1, 2, 3, 444L, 1100L, -1234, 11.72, 'hi there', u'\\u3030\\u3000', {'a': 1, 'c': [1, 2, 3], 'b': 2}, ('this', 'is', 'a', 'tuple'), True, None]"
>>> original_list == ast.literal_eval(retrieved_list.the_list)
True

这表明列表已经成功地通过数据库来回转换了。

2

根据Django文档:编写自定义模型字段,我创建了一个简单的字段LongListAsTextField()。这个字段是基于默认的django.db.models.TextField,它可以把一个长整型的列表转换成字符串,也可以把字符串转换回长整型列表,这个过程是通过to_pythonget_prep_value这两个方法来实现的。

models.py

from __future__ import absolute_import

from django.db import models

from .fields import LongListAsTextField

class Record(models.Model):
    parent_list = LongListAsTextField()

fields.py

从django.db导入模型

从django.utils.six导入with_metaclass

class LongListAsTextField(with_metaclass(models.SubfieldBase, models.TextField)):

    def to_python(self, value):
        if isinstance(value, list):
           return value

        return [
            long(val)
            for val in value.split(',')
            if val.isdigit()
        ]

    def get_prep_value(self, value):
        return ','.join([str(val) for val in value])

shell

Record(parent_list=[1,2]).save()
record = Record.objects.last()
record.parent_list # returns [1L, 2L]

撰写回答