0

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

我想要一个Many-to-many relationship介于两个模型之间的模型,为此,我使用的是ListField在里面djangotoolbox.fields

为了提供自定义表单字段,我已经用另一个类 ModelListField 覆盖了 ListField,如本问题中所述,它覆盖了 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”,即创建表 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 :-( 感谢您阅读冗长而无聊的描述..

4

1 回答 1

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)

我还遇到了 Select Widget 未显示 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)**

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

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

于 2013-02-23T21:05:12.217 回答