Newer
Older
from django.contrib.auth.decorators import login_required
from django.forms.models import ModelForm
from django.http import HttpResponseForbidden
from django.utils.decorators import method_decorator
from django.views import defaults
from django.views.generic import View
from django.views.generic.base import ContextMixin
from django.views.generic.detail import SingleObjectTemplateResponseMixin
from django.views.generic.edit import ModelFormMixin, ProcessFormView
def page_not_found(request, exception=None, template_name='apply/404.html'):
if not request.user.is_authenticated:
Todd Dembrey
committed
template_name = '404.html'
return defaults.page_not_found(request, exception, template_name)
@method_decorator(login_required, name='dispatch')
class ViewDispatcher(View):
admin_view: View = None
Fredrik Jonsson
committed
partner_view: View = None
community_view: View = None
applicant_view: View = None
def admin_check(self, request):
return request.user.is_apply_staff
Fredrik Jonsson
committed
return request.user.is_reviewer
def partner_check(self, request):
return request.user.is_partner
def community_check(self, request):
return request.user.is_community_reviewer
def dispatch(self, request, *args, **kwargs):
if self.admin_check(request):
view = self.admin_view
elif self.reviewer_check(request):
view = self.reviewer_view
Fredrik Jonsson
committed
elif self.partner_check(request):
view = self.partner_view
elif self.community_check(request):
view = self.community_view
if view:
return view.as_view()(request, *args, **kwargs)
return HttpResponseForbidden()
class DelegatableBase(ContextMixin):
"""
A view which passes its context to child form views to allow them to post to the same URL
`DelegateableViews` objects should contain form views that inherit from `DelegatedViewMixin`
and `FormView`
"""
form_prefix = 'form-submitted-'
def get_form_kwargs(self):
return {}
form_kwargs = self.get_form_kwargs()
forms = dict(form_view.contribute_form(**form_kwargs) for form_view in self.form_views)
Erin Mullaney
committed
form_prefix=self.form_prefix,
**forms,
**kwargs,
)
def post(self, request, *args, **kwargs):
# Information to pretend we originate from this view
kwargs['context'] = self.get_context_data()
kwargs['template_names'] = self.get_template_names()
for form_view in self.form_views:
if self.form_prefix + form_view.context_name in request.POST:
return form_view.as_view()(request, *args, **kwargs)
# Fall back to get if not form exists as submitted
return self.get(request, *args, **kwargs)
class DelegateableView(DelegatableBase):
def get_form_kwargs(self):
return {
'user': self.request.user,
'instance': self.object,
}
Erin Mullaney
committed
def post(self, request, *args, **kwargs):
self.object = self.get_object()
Erin Mullaney
committed
kwargs['submission'] = self.object
return super().post(request, *args, **kwargs)
class DelegateableListView(DelegatableBase):
def get_form_kwargs(self):
return {
'user': self.request.user,
}
def post(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
return super().post(request, *args, **kwargs)
Erin Mullaney
committed
class DelegatedViewMixin(View):
"""For use on create views accepting forms from another view"""
def get_template_names(self):
return self.kwargs['template_names']
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
def get_form(self, *args, **kwargs):
form = super().get_form(*args, **kwargs)
form.name = self.context_name
return form
def get_context_data(self, **kwargs):
# Use the previous context but override the validated form
form = kwargs.pop('form')
kwargs.update(self.kwargs['context'])
kwargs.update(**{self.context_name: form})
return super().get_context_data(**kwargs)
@classmethod
def is_model_form(cls):
return issubclass(cls.form_class, ModelForm)
def contribute_form(cls, **kwargs):
form = cls.form_class(**kwargs)
return cls.context_name, form
query = self.request.GET.urlencode()
if query:
query = '?' + query
return self.request.path + query
class CreateOrUpdateView(SingleObjectTemplateResponseMixin, ModelFormMixin, ProcessFormView):
def get(self, request, *args, **kwargs):
try:
self.object = self.get_object()
except self.model.DoesNotExist:
self.object = None
return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
try:
self.object = self.get_object()
except self.model.DoesNotExist:
self.object = None
return super().post(request, *args, **kwargs)