Reputation: 705
I have a Django template that has data from a few different model types combining to make it. A dashboard if you will. And each of those has an edit form.
Is it best to process all those forms in one view as they are posted back to the same place and differentiating between them by a unique field like below?
Or if having lots of different dedicated avenues is the way forward? Thanks for any guidance
class ProjectDetail(DetailView):
template_name = 'project/view.html'
def get_object(self):
try:
return Project.objects.filter(brief__slug=self.kwargs['slug']).filter(team=get_user_team(self.request)).first()
# add loop to allow multiple teams to work on the same brief (project)
except Exception as e:
project_error = '%s (%s)' % (e.message, type(e))
messages.error(self.request, 'OH NO! %s' % project_error)
return redirect('home')
def get_context_data(self, **kwargs):
project = self.get_object()
context = dict()
context['project'] = project
context['milestone_form'] = MilestoneForm(initial={'project': project})
context['view'] = self
return context
def post(self, request, *args, **kwargs):
# get the context for the page
context = self.get_context_data()
try:
# switch for each of the form types on the team profile page (shown if member)
if 'milestone_form_submit' in request.POST:
project=self.get_object()
# set date arbitrarily to half way to brief deadline
brief = Brief.objects.get(project=project)
last_milestone = self.milestones().last()
milestone_del_date = last_milestone.del_date + timedelta(days=7)
new_milestone = Milestone(
project=project,
title_text=request.POST.get('title_text'),
del_date=milestone_del_date,
)
try:
new_milestone.save()
messages.success(self.request, "Excellent! New delivery popped on the bottom of the list")
except Exception as e:
# pass the erroring form back in the context if not
form = MilestoneForm(request.POST)
context['milestone_form'] = form
messages.error(self.request, "OH NO! Deadline didn't save. Be a sport and check what you entered")
elif 'milestone-edit-date-form-submit' in request.POST:
# get object from db
milestone = Milestone.objects.get(pk=request.POST['id'])
# update del_date field sent
milestone.del_date = request.POST['del_date']
# save back to db
milestone.save()
messages.success(self.request, "Updated that delivery right there!")
elif ...
except Exception as e:
messages.error(self.request, "OH NO! Deadline didn't save. Be a sport and check what you entered")
return render(request, self.template_name, context)
Upvotes: 2
Views: 7218
Reputation: 1382
You can use mixins in order to solve your problem.
Example from the gist https://gist.github.com/michelts/1029336
class MultipleFormsMixin(FormMixin):
"""
A mixin that provides a way to show and handle several forms in a
request.
"""
form_classes = {} # set the form classes as a mapping
def get_form_classes(self):
return self.form_classes
def get_forms(self, form_classes):
return dict([(key, klass(**self.get_form_kwargs())) \
for key, klass in form_classes.items()])
def forms_valid(self, forms):
return super(MultipleFormsMixin, self).form_valid(forms)
def forms_invalid(self, forms):
return self.render_to_response(self.get_context_data(forms=forms))
As you can see, when you inherit from this class, you can handle multiple forms simultaneously. Look at the gist's code and adapt it to your problem.
Look at this answer
Upvotes: 6