Похоже, что наилучшим способом было бы через множество отношений, например:
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 таким способом действительно мощно. Да, вы в основном получаете список языков ISO в таблице SQL, но это проблема? Если это так, вы всегда можете заменить его на
строка и использовать 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
. Это именно так, как звучит - следует всем внешним ключам, поэтому ваша база данных получает один массивный удар, а затем остается один, поскольку объекты находятся в памяти (кэшируются).