#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. Но есть разница в возврате «недопустимой формы» и «начальной пустой формы» — в последнем случае на странице не должно быть ошибок.