0

我正在編寫基於Django-Nonrel的應用程序並使用Django提供的管理視圖功能。無法使用django管理視圖將django-toolbox ListField保存到數據庫

我希望有一個模型Many-to-many relationship兩者之間,爲此,我使用內部djangotoolbox.fields

發現ListField提供自定義表單字段,我已重寫ListField具有如this question描述另一個類ModelListField它覆蓋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] 

和查詢& PARAMS通過調用是:

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

在創建模型,我指定的標記列的類型爲「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 :-( 感謝您閱讀長&無聊說明沒有很好的例子..

+0

你用django-nonrel和SQLite作爲後端?這很奇怪。你應該使用django,而不是django-nonrel。 – dragonx 2013-02-23 19:15:41

+0

我正在更改django應用程序的django-nonrel將用於不同的後端..我將盡快更改後端,但我不認爲有任何django-nonrel和sqlite之間的不兼容問題。 – 2013-02-23 19:41:44

+0

ListFields不映射到sqlite後端的任何東西。所以你的問題是django-nonrel與sqlite不兼容。 – dragonx 2013-02-23 19:47:43

回答

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) 

我也面臨着選擇的Widget並沒有顯示PK> 10爲選擇代碼的問題編輯。 裏面Django的非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與列表作爲字符串,即所謂的「[1,2,3]」而不是僅僅是[1,2,3],所以使用eval將字符串轉換回列表。 不知道這兩個是相關的還是後一個問題是與Django-Nonrel的錯誤。

正如dragonx所說,用sqlite3和django-nonrel測試可能不是個好主意。 我將很快改變我的後端。