Django: параметрические представления на основе классов - PullRequest
7 голосов
/ 25 июня 2011

Я пытаюсь использовать универсальный класс CreateView для обработки форм для набора моделей, унаследованных от одного базового класса.

class BaseContent(models.Model):
    ...

class XContent(BaseContent):
    ...

class YContent(BaseContent):
    ...

Для сохранения СУХОГО я хочу определить один класс CreateView, который будет обрабатывать все унаследованные классы от BaseContent.

Шаблон URL для этого представления:

url(r'^content/add/(?P<model_name>\w+)/$', ContentCreateView.as_view(), name='content_add')

Примерно так должно работать:

class ContentCreateView(CreateView):
    template_name = 'content_form.html'

    def get_model(self, request):
        # 'content' is the name of the application; model_name is 'xcontent', 'ycontent', ...
        return ContentType.objects.get_by_natural_key('content', self.model_name)

Но я получаю это исключение:

ContentCreateView is missing a queryset. Define ContentCreateView.model, ContentCreateView.queryset, or override ContentCreateView.get_object().

Это предложение, похоже, не выполняется, так как я не желаю устанавливать атрибут класса, такой как model или queryset, чтобы сохранить динамически генерируемую форму модели.Переопределение get_object не похоже на создание объекта.

Я попытался переопределить get_queryset(), но этот метод не принимает параметр request и не имеет доступа к self.model_name, который исходит из шаблона URL.

Короче говоря, как можноЯ заставляю CreateView использовать динамическую форму, основанную на параметре, переданном из URL?

Спасибо.

Ответы [ 2 ]

1 голос
/ 10 декабря 2015

Имела эту проблему какое-то время, но нашла решение. Вам необходимо переопределить метод отправки, определенный в as_view () (django.views.generic.base), примерно так:

class ContentCreateView(CreateView):    
    def dispatch(self, request, *args, **kwargs):
        for app in ['foo', 'bar']:
            model = models.get_model(app, kwargs['modelname'])
            if model:
                self.model = model
                break

        return super(GenericEdit, self).dispatch(request, *args, **kwargs)
    ...
    ...
1 голос
/ 27 июня 2011

Вы можете установить атрибут model из вашего urls.py, в зависимости от вызываемого URL:

url(r'^content/add/x/$', 
    ContentCreateView.as_view(model=XContent), name='x_content_add'),
url(r'^content/add/y/$', 
    ContentCreateView.as_view(model=YContent), name='y_content_add')

Я признаю, что он не идеален, поскольку вы немного повторяетесь, но поэтому выесть преимущество в том, чтобы иметь разные имена для одного и того же вида, в зависимости от модели!Кроме того, вы можете сделать что-то подобное с переопределением form_class ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...