Джанго: как писать models.py - PullRequest
0 голосов
/ 30 июня 2011

В приложении у меня есть модель Post. В админ-панели я хочу иметь только одну запись - «Посты» с одной ссылкой для добавления поста. В списке сообщений в админе я хочу видеть их все.

У всех сообщений есть заголовок, содержание и другие основные поля.

Но:

Из-за источника сообщений посты могут иметь разные поля.

Sources:

--- First
--- Second
--- Third
--- ......

Например, сообщение с первым источником должно иметь опрос (но не имеет категории). Публикация со вторым источником должна принадлежать категории в ветви категории №1 (но не имеет опроса). Сообщение с третьим источником может иметь поле Изображение (но без категории и без опроса) и т. Д.

Category branch #1

--- cb1_first
--- cb1_second
--- cb1_third

Category branch #....

--- cb2_first
--- cb2_second
--- cb2_third

Итак, на странице добавления поста я хочу написать заголовок, контент, другие основные вещи, кроме того, что я выбираю Источник, и из-за выбора появляются другие поля (для первого источника это опрос, для второго - список категорий в ветке Категория # 1 и т. Д.).

Если я создаю базовый класс Post, а затем расширяю его другими классами, я получу дополнительные таблицы в SQL и многие элементы в администраторе приложения (т. Е. Добавлю базовую запись, добавлю видео-запись, добавлю запись с опросом, добавлю публикацию с ветка категории № 2 ...)

Обращайтесь за советом, как организовать такое приложение.

Ответы [ 2 ]

1 голос
/ 30 июня 2011

Это причина, почему я решительный противник проверки на уровне базы данных с такими вещами, как null = False. Создайте одну модель Post со всеми полями, которые может иметь любой тип публикации, но не применяйте требования к модели (blank=True, null=True).

Затем вместо этого проверьте, что в ваших формах требуется то или иное поле и т. Д., Особенно ModelForms при работе с администратором.

Если в одном случае требуется определенное поле, вы можете принудительно ввести его, используя:

class MyModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(MyModelForm, self).__init__(*args, **kwargs)

        if self.instance.source == 'first':
            self.fields['poll'].required = True

Затем, чтобы показать только фактические поля, которые должны отображаться на основе источника, вы можете либо немного поработать с JavaScript, либо вы можете явно исключить их из администратора с помощью ModelAdmin.get_fieldsets(). В основном процесс таков:

class MyModelAdmin(admin.ModelAdmin):
    ...
    fieldsets = (
        (None, { 'fields': ('common_field_1', 'common_field_2', 'common_field_3',),
    )
    poll_fieldsets = (
        (None, { 'fields': ('common_field_1', 'common_field_2', 'common_field_3', 'poll',),
    )

    def get_fieldsets(self, request, obj=None):
        if obj and obj.source == 'first':
            return self.poll_fieldsets
        else:
            return super(MyModelAdmin, self).get_fieldsets(request=request, obj=obj)
0 голосов
/ 30 июня 2011

Сначала создайте модель с теми базовыми полями, которые требуются для публикации (скажем, Post модель). Затем вы можете создать модель для источников - Source модель. Модель Post должна иметь внешний ключ, представляющий источник, с которым она была создана. Модель Source должна содержать поле для хранения имени модели, которую нужно создать для хранения дополнительных полей сообщений с указанным источником. Затем создайте все модели для каждого дополнительного набора полей, который вам требуется. У каждого должно быть поле внешнего ключа с моделью Post. Например, вы можете создать модель Poll с внешним ключом Post.

После моделирования данных, подобных этим, вы можете просто обратиться к модели Source, чтобы разрешить все типы полей при создании сообщений и их получении.

...