无法使用django管理视图将django-toolbox ListField保存到数据库

时间:2013-02-23 18:24:25

标签: django django-models django-forms django-admin django-nonrel

我正在编写一个基于django-nonrel的应用程序,并使用Django提供的管理视图功能。

我想在两个模型之间使用Many-to-many relationship,为此,我使用ListField内的djangotoolbox.fields

为了提供自定义表单字段,我使用另一个类ModelListField覆盖了ListField,如this question中所述,它覆盖了formfield函数以返回MultipleChoiceField表单小部件。

视图部分工作正常,但我无法使用sqlite3后端保存模型。

假设有两个模型(注释和标签之间的标准多对多关系)

from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=255)

class Note(models.Model):
    tags = ModelListField(db.ForeignKey(Tag))

通过这些更改,在管理界面中正确显示添加注释页面,但是当我尝试保存注释时,出现以下异常:

InterfaceError, Error binding parameter 0 - probably unsupported type.  
inside django\db\backends\sqlite3\base.py in execute, line 234

第234行如下:

class SQLiteCursorWrapper(Database.Cursor):
    """
    Django uses "format" style placeholders, but pysqlite2 uses "qmark" style.
    This fixes it -- but note that if you want to use a literal "%s" in a query,
    you'll need to use "%%s".
    """
    def execute(self, query, params=()):
        query = self.convert_query(query)
        try:
234 ---->           return Database.Cursor.execute(self, query, params)
        except Database.IntegrityError, e:
            raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]
        except Database.DatabaseError, e:
            raise utils.DatabaseError, utils.DatabaseError(*tuple(e)), sys.exc_info()[2]

查询&传递给电话的参数是:

query: 'INSERT INTO "note" ("tags") VALUES (?)'  
params: [1, 2, 3]
where 1, 2, 3 are pk of three tag fields in database.

创建模型时,我将COLUMN TYPE标签指定为“ListField”,即 CREATE表的SQL查询是:

CREATE TABLE "notes" (
    "id" integer NOT NULL PRIMARY KEY,
    "tags" ListField NOT NULL
)

数据库查询在看到列表[1,2,3]时执行barfs上方的调用。 我尝试将列表作为smart_unicode(list)传递,或者只是将字符串"1 2 3"传递给而不是列表,但是ListField在验证时(在get_db_prep_value中)会抛出错误,因为它需要列表。

我无法理解将列表对象传递给上面的Database.Cursor.execute调用是否正确或者因为ListField正确期望列表而丢失了某些内容但是在写入数据库时​​,有人应该转换此列表进入字符串等..?

没有关于如何使用ListField的好例子:-( 感谢阅读漫长的&无聊的描述..

1 个答案:

答案 0 :(得分:0)

我发现get_db_prep_save负责以正确的格式准备数据以保存到数据库。 因此,在ModelListField中,我重写get_db_prep_save并将其转换为字符串以修复“不支持的类型”错误。

def get_db_prep_save(self, value, connection):
    retval = super(ModelListField, self).get_db_prep_save(value)
    return unicode(retval)

我还遇到了一个问题,选择小工具没有显示带有pk>标签的标签。 10选中。 里面的django-non 1.3, 我必须在下面的函数中添加eval:

class Select(Widget):
    def render_options(self, choices, selected_choices):
        **if(type(selected_choices) != list):
            selected_choices = eval(selected_choices)**

这样做是因为使用list作为字符串调用了render_option,即“[1,2,3]”而不是[1,2,3],因此使用eval将字符串转换回列表。 不确定这两个是否相关或后一个问题是django-nonrel的错误。

正如dragonx所说,使用sqlite3和django-nonrel进行测试也许不是一个好主意。 我很快就会改变我的后端。