我正在存儲描述語言資源的OLAC metadata。元數據的許多元素都是可重複的 - 例如,一個資源可以有兩種語言,三個作者和四個與之關聯的日期。如何在Django中存儲多個相同字段的副本?
有沒有什麼方法將它存儲在一個模型中?爲每個可重複的元數據元素定義一個模型似乎有些過分 - 特別是因爲模型只有一個字段:它是有價值的。
我正在存儲描述語言資源的OLAC metadata。元數據的許多元素都是可重複的 - 例如,一個資源可以有兩種語言,三個作者和四個與之關聯的日期。如何在Django中存儲多個相同字段的副本?
有沒有什麼方法將它存儲在一個模型中?爲每個可重複的元數據元素定義一個模型似乎有些過分 - 特別是因爲模型只有一個字段:它是有價值的。
這聽起來像是最好的方式通過許多將是一對多的關係,就像這樣:
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
。這聽起來確實如此 - 遵循所有的外鍵,所以你的數據庫會被大量地擊中,然後隨着對象在內存(緩存)中被單獨留下。
你也可以選擇做一個'標籤'元素。這可能有兩個字段,一個類型和一個值。事情是這樣的:
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但我更願意把它成爲一個獨立的模型,因爲你可以使用管理界面輸入一系列的類型,然後選擇它們當你想添加一個新標籤時從下拉菜單中選擇。
編輯:我應該注意,上面的解決方案更好,因爲它會使以後處理數據更容易。如果你打算做的不僅僅是輸入這些信息,我建議定義完整的模型。
「看起來像是過度殺傷力」?真?這就是數據庫應該如何工作的原因。你爲什麼要正確使用數據庫「矯枉過正」? – 2011-02-01 23:18:46