from django.urls import reverse_lazy from django.http import HttpResponseRedirect from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic import (View, TemplateView, ListView, CreateView, DetailView) from django.views.generic.detail import SingleObjectMixin from django.contrib import messages from django.shortcuts import get_object_or_404 from rules.contrib.views import PermissionRequiredMixin from .models import Job, Application, Question from .forms import JobForm, QuestionFormSet, ApplicationForm, AnswerForm class Index(TemplateView): template_name = 'jobs/index.html' def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['jobs'] = Job.objects.all().order_by('-updated')[:6] return context class JobList(ListView): context_object_name = 'jobs' model = Job class JobDetail(DetailView): context_object_name = 'job' model = Job class JobRenew(LoginRequiredMixin, PermissionRequiredMixin, SingleObjectMixin, View): model = Job permission_required = 'jobs.change_job' http_method_names = ['post'] def post(self, request, *args, **kwargs): job = self.get_object() job.renew() messages.add_message( request, messages.SUCCESS, 'Job has been renewed until {}.'.format( job.expires.isoformat(' ', 'seconds'))) return HttpResponseRedirect(job.get_absolute_url()) class JobCreate(LoginRequiredMixin, CreateView): model = Job form_class = JobForm success_url = reverse_lazy("jobs:job_list") def get(self, request, *args, **kwargs): self.object = None form = self.get_form(self.get_form_class()) question_form = QuestionFormSet() return self.render_to_response( self.get_context_data(form=form, question_form=question_form)) def post(self, request, *args, **kwargs): self.object = None form_class = self.get_form_class() form = self.get_form(form_class) question_form = QuestionFormSet(self.request.POST) if (form.is_valid() and question_form.is_valid()): return self.form_valid(form, question_form) else: return self.form_invalid(form, question_form) def form_valid(self, form, question_form): self.object = form.save(commit=False) self.object.posted_by = self.request.user self.object.save() form.save_m2m() question_form.instance = self.object question_form.save() return HttpResponseRedirect(self.get_success_url()) def form_invalid(self, form, question_form): return self.render_to_response( self.get_context_data(form=form, question_form=question_form)) class ApplicationCreate(LoginRequiredMixin, CreateView): # TODO: restrict users from re-application model = Application form_class = ApplicationForm success_url = reverse_lazy("jobs:job_list") def get_question_queryset(self): # filter questions for particular job and order it so same queryset # can be used stably as initial params for GET and POST requests return Question.objects.filter( job_id=self.kwargs['job_pk']).order_by('id') def get_answer_formset(self, *args): questions = self.get_question_queryset() return AnswerForm.inlineformset_factory(extra=questions.count())( initial=[{ 'question': q.id } for q in questions], *args) def get(self, request, *args, **kwargs): self.object = None form = self.get_form(self.get_form_class()) answer_form = self.get_answer_formset() return self.render_to_response( self.get_context_data(form=form, answer_form=answer_form)) def post(self, request, *args, **kwargs): self.object = None form_class = self.get_form_class() form = self.get_form(form_class) answer_form = self.get_answer_formset(self.request.POST) if (form.is_valid() and answer_form.is_valid()): return self.form_valid(form, answer_form) else: return self.form_invalid(form, answer_form) def form_valid(self, form, answer_form): self.object = form.save(commit=False) self.object.applicant = self.request.user self.object.job = get_object_or_404(Job, id=self.kwargs['job_pk']) self.object.save() form.save_m2m() answer_form.instance = self.object answer_form.save() messages.add_message( self.request, messages.SUCCESS, 'Your application has been succesfully received.') return HttpResponseRedirect(self.get_success_url()) def form_invalid(self, form, answer_form): return self.render_to_response( self.get_context_data(form=form, answer_form=answer_form)) class ApplicationList(LoginRequiredMixin, PermissionRequiredMixin, ListView): model = Application context_object_name = 'applications' permission_required = 'jobs.change_job' def get_permission_object(self): return get_object_or_404(Job, id=self.kwargs['job_pk']) def get_queryset(self): return super().get_queryset().filter(job_id=self.kwargs['job_pk']) class ApplicationDetail(LoginRequiredMixin, DetailView): model = Application