Как не нарушать принцип DRY в представлении? Лучшие практики
Существует представление OrderItemEdit:
class OrderItemEdit(View):
def get(self, request, number, order_item_id):
# Если в сесси есть номер заказа
if 'new_order' in request.session.keys():
order_number = request.session['new_order_number']
# Проверка number
# Если url number совпадает со значение в сессии
if number == order_number:
# Проверка order_item_id
order = Order.objects.get(number=order_number)
order_items = OrderItem.objects.filter(order=order)
order_item = OrderItem.objects.filter(id=order_item_id)
# Если найден order_item с таким id
if order_item:
order_item = order_item[0]
# Если order_item соответствует текущему order
if order_item in order_items:
format = order_item.format
border = order_item.border
form = OrderItemEditForm(initial={
'format': format,
'border': border,
})
context = {}
context['form'] = form
context['order_number'] = order_number
context['order_item_id'] = order_item_id
return render(request, 'store/new_order_item_edit.html', context)
else:
return redirect('/order/{}/edit/'.format(order_number))
else:
return redirect('/order/{}/edit/'.format(order_number))
# Если url number не совпадает со значением в сессии
elif number != order_number:
return redirect('/order/{}/edit/'.format(order_number))
else:
return redirect('/order/new/')
def post(self, request, number, order_item_id):
# Если в сесси есть номер заказа
if 'new_order' in request.session.keys():
order_number = request.session['new_order_number']
# Проверка number
# Если url number совпадает со значение в сессии
if number == order_number:
# Проверка order_item_id
order = Order.objects.get(number=order_number)
order_items = OrderItem.objects.filter(order=order)
order_item = OrderItem.objects.filter(id=order_item_id)
# Если найден order_item с таким id
if order_item:
order_item = order_item[0]
# Если order_item соответствует текущему order
if order_item in order_items:
form = OrderItemEditForm(request.POST)
# Если форма валидна
if form.is_valid():
format = form.cleaned_data.get('format')
border = form.cleaned_data.get('border')
order_item.format = format
order_item.border = border
order_item.save()
return redirect('/order/{}/edit/'.format(order_number))
else:
return redirect('/order/{}/edit/item/{}/'.format(order_number, order_item.id))
else:
return redirect('/order/{}/edit/'.format(order_number))
else:
return redirect('/order/{}/edit/'.format(order_number))
# Если url number не совпадает со значением в сессии
elif number != order_number:
return redirect('/order/{}/edit/'.format(order_number))
else:
return redirect('/order/new/')
И в get, и в post запросах есть одинаковые проверки, части кода. Также и в других представлениях некоторые части кода повторяются. Хотел бы уточнить: как вынести проверки и другие части кода так, чтобы это было структурно правильно, повторяемо и не нарушало принцип don't repeat yourself.
Обновлено 1 Пришла на ум идея создать shortcuts.py и вынести туда проверки. Например:
shortcuts.py
def check_session_new_order(session):
if 'new_order' in session.keys():
return True
else:
return False
views.py
if check_session_new_order(request.session):
order_number = request.session['new_order_number']
...
Не уверен что мой подход корректен, но все же оставлю это здесь.
Ответы (1 шт):
Да, ваш вариант один из часто используемых. Так же можно вынести его в отдельный пакет, в котором держать модули логики, и импортировать для работы. Вот тут, например, более подробно об архитектуре. Но вкратце - всё то же, что я сказал выше.