Reputation: 1777
We've got a lot, a lot of views that utilize simple generic views that we used to loop over in urls.py and point to the same function based generic view. Now that we're moving to class based generic views, we need to replicate this functionality and we're being forced to move all of the logic into the urls.py file, like this:
GENERIC_VIEWS_EDIT = ['ModelOne', 'ModelTwo', 'ModelThree', 'ModelFour', 'ModelN',]
for model in GENERIC_VIEWS_EDIT:
urlpatterns += patterns('',
url(r'^%s/(?P<pk>\d+)/$' % model.lower(), never_cache(staff_member_required(UpdateView.as_view(
model=eval(model),
context_object_name='object',
form_class=eval('%sForm' % model),
template_name='edit_form.html',
success_url='/yay/'
))), name='edit-%s' % model.lower()),
)
While this works fine, I disdain having all of this "view code" in the urls.py file. Furthermore, if I need to override a method for one or two of these N models, this implementation makes that impossible.
Is there any way I can pass the model as an argument and move my generic view back into views.py, something like this?
GENERIC_VIEWS_EDIT = ['ModelOne', 'ModelTwo', 'ModelThree', 'ModelFour', 'ModelN',]
for model in GENERIC_VIEWS_EDIT:
urlpatterns += patterns('',
url(r'^%s/(?P<pk>\d+)/$' % model.lower(), UpdateView.as_view(model=model)), name='edit-%s' % model.lower()),
)
Upvotes: 1
Views: 955
Reputation: 737
You're right. This logic belongs in your View.
Since you're using Class Based Views, you can just subclass UpdateView and override the __init__()
function with custom logic:
class MyUpdateView(UpdateView):
template_name = 'edit_form.html'
success_url = '/yay/'
context_object_name = 'object'
def __init__(self, *args, **kwargs):
super(MyUpdateView, self).__init__(*args, **kwargs)
self.form_class = eval('%sForm' % self.model)
Upvotes: 1