Используя моделирование в django, как правильно расширить модель?
Я разработчик-любитель, который изучает python, чтобы создать свой первый полнофункциональный проект, который представляет собой сайт обмена животными для игры, в которую я играю. Животные могут иметь до 3 признаков, но некоторые из них имеют особые признаки. В случае животных с особыми чертами я попытался расширить базовую модель и добавить дополнительные черты, используя предложенную кем-то нотацию, но, похоже, это не работает. Я знаю, что технически я могу просто скопировать базовый набор признаков и добавить их вручную, каждый раз с другой моделью, но это, кажется, раздует мой код, а я хотел бы быть эффективным в этом деле. Если вы заметили что-то еще, что можно улучшить, пожалуйста, дайте мне знать, спасибо.
Это нормально, если вы хотите, чтобы ваши драконы были отдельно от других животных, но у меня такое чувство, что вам это не нужно. Скажем, если вы хотите получить всех животных, вы не сможете просто сделать Animal.objects.all()
, вам придется сделать Dragon.objects.all(), ...
и т.д. для каждого из них.
Я бы рекомендовал следующую реструктуризацию:
- Перенесите все варианты выбора в отдельные модели, на мой взгляд, их слишком много, и они повторяются и жестко закодированы.
# Instead of
FIRST_TRAIT_CHOICES = [
(BIGBONED, 'Big Boned'),
... etc.
# do
class Trait(models.Model):
name = models.CharField(...
animal_types = models.ManyToManyField(...
# ^ m2m as many animals can have many trains
- Обратите внимание на поле
animal_types
выше - создайте другую модель, которая отражает тип животного, например, Дракон:
class AnimalType(models.Model):
name = models.CharField(... # e.g. Dragon, etc.
- Затем прикрепите это к модели животного - вы также можете сделать это для признаков. Это делает ее гораздо более управляемой и динамичной, а также удаляет много лишнего из кода модели.
class Animal(models.Model):
animal_type = models.ForeignKey(AnimalType, ...
first_trait = models.ForeignKey(Trait, ...
... etc.
Возвращаясь к признакам, вы можете создать логику, чтобы только определенные типы животных могли обладать определенными признаками.
Это делает ваш код намного чище, вы заносите все данные в базу данных, что делает их более легко редактируемыми. Это также означает, что в случае изменения признаков или типов животных вам не придется массово обновлять поля символов, вы просто измените запись в базе данных.
Наконец, вы можете получить всех драконов таким образом, не удаляя возможность иметь драконов и других животных вместе в кверисете:
dragons = Animal.objects.filter(animal_type__name="dragon")