我正在编写一个基于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的好例子:-( 感谢阅读漫长的&无聊的描述..
答案 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进行测试也许不是一个好主意。 我很快就会改变我的后端。