【发布时间】:2012-07-12 18:38:00
【问题描述】:
我已经构建了一个应用程序,该应用程序具有许多应该能够使用相同基本代码的相似视图。然而,每种方法在方法内的不同拐点处都具有某些独特的特征,因此我无法找到一种方法来构造它以实际重用任何代码。相反,我创建了一种剪切和粘贴方法,并单独调整了每种方法。应用程序的这一部分是我编写的第一个 Python 代码,并且知道必须有更好的方法来做到这一点,但我被锁定在这样做并且“它有效”,所以我看不到出路.
下面是基本视图模板的基本外观:
def view_entity(request, entity_id=None):
if request.method == 'POST':
return _post_entity(request, entity_id)
else:
return _get_entity(request, entity_id)
def _get_entity(request, entity_id):
data = _process_entity(request, entity_id)
if 'redirect' in data:
return data['redirect']
else:
return _render_entity(request, data['form'])
def _post_entity(request, entity_id):
data = _process_entity(request, entity_id)
if 'redirect' in data:
return data['redirect']
elif data['form'].is_valid():
# custom post processing here
instance = data['form'].save()
return HttpResponseRedirect(reverse('entity', args=[instance.id]))
else:
return _render_entity(request, data['form'])
def _process_entity(request, entity_id):
data = {}
if entity_id != 'new': # READ/UPDATE
# sometimes there's custom code to retrieve the entity
e = entity_id and get_object_or_404(Entity.objects, pk=entity_id)
# sometimes there's custom code here that deauthorizes e
# sometimes extra values are added to data here (e.g. parent entity)
if e:
if request.method == 'POST':
data['form'] = EntityForm(request.POST, instance=e)
# sometimes there's a conditional here for CustomEntityForm
else:
data['form'] = EntityForm(instance=e)
else: # user not authorized for this entity
return {'redirect': HttpResponseRedirect(reverse('home'))}
# sometimes there's custom code here for certain entity types
else: # CREATE
if request.method == 'POST':
data['form'] = EntityForm(request.POST)
else:
data['form'] = EntityForm()
# sometimes extra key/values are added to data here
return data
我什至没有包括所有可能的变化,但正如您所见,_process_entity 方法需要根据正在处理的实体类型进行大量个性化定制。这是我无法找到处理此问题的 DRY 方法的主要原因。
感谢任何帮助,谢谢!
【问题讨论】:
-
你使用的是什么版本的 Django?如果是 Django 1.3 或更高版本,您可以使用基于类的视图来使您的视图更加 DRY。
-
我使用的是 Django 1.3。你能详细说明一下吗?
-
参见docs.djangoproject.com/en/dev/topics/class-based-views - 每个视图都是一个类,它允许您使用和重用其他视图的功能。但是您的视图似乎做了很多事情:它创建对象、加载对象、呈现多种不同的形式、执行重定向——这太多了。这一切都需要在 URL 上完成吗?否则我会将其重构为多个视图。
-
感谢您的参考。如果没有更深入的洞察力的人碰巧提供有用的基本起点,我将尝试弄清楚如何自己重构为多个视图。 :)
标签: python django model-view-controller dry