Упрощение логики обработки форм представлений Django

#python #django

#python #django

Вопрос:

Просто выстрел в темноте, но, возможно, кто-то может предложить что-то интересное.

Всякий раз, когда у меня есть формы, на мой взгляд, есть много операторов if-else, и трудно следовать логике. Существует ли какой-либо шаблон или функция языка python для упрощения этого? У меня была эта проблема, сколько я себя помню, и по сей день не нашел хорошего решения.

Вот пример: представление, которое отображает ту же страницу, если есть ошибки, и если все хорошо, выполняет поиск (по модели) и возвращает страницу с графиками:

 def analysis(request):
    context = {'main_navigation' : 'analysis'}
    context['no_results'] = False
    template = 'analysis/analysis.html'

    # Search params?
    if not request.GET:
        form = AnalysisSearchForm()
        context['form'] = form
    else:
        form = AnalysisSearchForm(request.GET)
        context['form'] = form
        if form.is_valid():            
            # Do the search
            results = form.search()

            if len(results) > 0:                
                context['results'] = json.dumps(results, default=encode)
                context.update(form.cleaned_data)

                # Add the compare form
                context['compare_form'] = CompareForm();

                # Add critical level if there is one.
                part = form.cleaned_data.get('part', None)
                if part:
                    level = Level.get(part, "Default")
                    if level is not None:
                        context['level'] = level.value

                template = 'analysis/analysis_graphs.html'
            else:                                
                context['no_results'] = True

    return render_to_response(template, context,
                              context_instance=RequestContext(request))
 

Как вы можете видеть, вышесказанное уже упрощено путем перемещения всей логики запросов в метод form.search() , который использует cleaned_data формы для (в данном случае) связи с удаленным API и получения результатов.

Комментарии:

1. Вы могли бы взять содержимое одного из ваших операторов if и выделить его как отдельную функцию.

Ответ №1:

Вы смотрели на представления на основе классов (новые в 1.3). Вы пишете свои представления как классы и наследуете необходимую функциональность от нескольких базовых представлений, а также миксинов. Это означает, что вы можете разбить свои представления на составляющие их части и иметь хорошее разделение кода:

https://docs.djangoproject.com/en/dev/topics/class-based-views/

Кроме того, существуют микшины, созданные специально для работы с формами:

https://docs.djangoproject.com/en/dev/ref/class-based-views/#formmixin

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

Комментарии:

1. Вау, это выглядит интересно! Теперь читаем страницу представлений на основе классов. Используете ли вы микширование форм? Каков пример их использования?

2. Я использую представления на основе классов, но мне еще не приходилось создавать форму. Примером использования может служить любое время, когда вы обрабатываете форму в своем представлении!

3. Хм… Мне трудно понять, как это относится ко мне. Кажется, что микшины выполняют много перенаправления, тогда как в моем случае все это в методе GET и многих операторах if…

Ответ №2:

Вот как я буду делать (с небольшими изменениями и переходами я не нарушал логику функций):

 # XXX: Use Dependency injection with the template file.
def analysis(request, template='analysis/analysis.html'): 
    context = {'main_navigation' : 'analysis'}
    context['no_results'] = False

    # XXX: Create only one form here without the need for if else.
    form = AnalysisSearchForm(request.GET or {})
    context['form'] = form

    if form.is_valid():            
        # The rest of your code here ... .
 

Комментарии:

1. Да, интересно… но будет ли форма действительной, если она пуста? И не будет ли это показывать ошибку при начальной загрузке страницы?

2. @drozzy: AFAIK пустая форма всегда недействительна, вы можете проверить это в своей командной строке python: from django.forms import From; print Form().is_valid() я верну False.

3. Но есть разница в возврате «недопустимой формы» и «начальной пустой формы» — в последнем случае на странице не должно быть ошибок.