2011-02-01 80 views
1

我正在存儲描述語言資源的OLAC metadata。元數據的許多元素都是可重複的 - 例如,一個資源可以有兩種語言,三個作者和四個與之關聯的日期。如何在Django中存儲多個相同字段的副本?

有沒有什麼方法將它存儲在一個模型中?爲每個可重複的元數據元素定義一個模型似乎有些過分 - 特別是因爲模型只有一個字段:它是有價值的。

+2

「看起來像是過度殺傷力」?真?這就是數據庫應該如何工作的原因。你爲什麼要正確使用數據庫「矯枉過正」? – 2011-02-01 23:18:46

回答

4

這聽起來像是最好的方式通過許多將是一對多的關係,就像這樣:

class author(models.Model): 
    # fields? 

class language(models.Model): 
    iso_lang_code = models.CharField() # probably need some constraints here 

class resource(models.Model): 
    name = models.CharField() 
    authors = models.ManyToManyField(Author) 
    languages = models.ManyToManyField(Language) 

然後當它涉及到創建資源,你只需要做:

r = resource(name="") 
a1 = author(name="ninefingers") 
a2 = author(name="jon skeet", type="god") 
r.authors.add(a1) 
r.authors.add(a2) 
english = languages.objects.get(iso_lang_code="en-GB") 
r.add(english) 
r.save() 

你也可以做一些很花哨的東西,比如:

english = languages.objects.get(iso_lang_code="en-GB") 
resourcesinenglish = english.resource_set.all() 

for r in resourcesinenglish: 
    # do something on r. 

所以使用ORM這種方式真的是力量FUL。是的,你基本上最終得到一個SQL表中的ISO語言列表,但這是一個問題嗎?如果是這樣,您可以隨時將其替換爲 字符串,並使用objects.filter(language='en-GB')(大致)轉換爲sql的 WHERE language='en-GB'。當然,你只限於一種語言。

另一種方法可能是寫所有的語言,通過分離器修改ISO代碼,說;然後做

r = resource.objects.get(id=701) 
langs = r.languages.split(';') 
for l in language: 
    print l 

當然,維持上述列表變成這樣更加困難。我認爲ORM比較容易。

至於更復雜的類型,如Authors ORM是迄今爲止最簡單的方法。

請注意,如果您擔心正在創建的數據庫請求的數量,則始終可以使用select_near。這聽起來確實如此 - 遵循所有的外鍵,所以你的數據庫會被大量地擊中,然後隨着對象在內存(緩存)中被單獨留下。

0

你也可以選擇做一個'標籤'元素。這可能有兩個字段,一個類型和一個值。事情是這樣的:

class TagType(models.Model): 
    name = models.CharField(max_length=50) 

class Tag(models.Model): 
    type = models.ManyToManyField(TagType) 
    value = models.CharField(max_length=200) 

class Resource(models.Model): 
    name = models.CharField(max_length=50) 
    tag = models.ManyToManyField(Tag) 

你可以選擇只具有標籤類型是charfield但我更願意把它成爲一個獨立的模型,因爲你可以使用管理界面輸入一系列的類型,然後選擇它們當你想添加一個新標籤時從下拉菜單中選擇。

編輯:我應該注意,上面的解決方案更好,因爲它會使以後處理數據更容易。如果你打算做的不僅僅是輸入這些信息,我建議定義完整的模型。

相關問題