From: Emilie Date: Thu, 8 Sep 2016 14:45:59 +0000 (+0200) Subject: JobOffer : List / Detail View + upload form X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=4071cff0d80352b799666dfaea4e2898f9d72b24;p=mezzo.git JobOffer : List / Detail View + upload form --- diff --git a/app/organization/pages/forms.py b/app/organization/pages/forms.py index fca71ef5..9d3782d6 100644 --- a/app/organization/pages/forms.py +++ b/app/organization/pages/forms.py @@ -2,11 +2,14 @@ from dal import autocomplete import dal_queryset_sequence import dal_select2_queryset_sequence + +from django import forms +from django.forms.widgets import HiddenInput +from django.forms import ModelForm from mezzanine.core.models import Orderable from organization.magazine.models import Article, Topic, Brief from organization.pages.models import CustomPage -# from mezzanine_agenda.models import Event -from organization.pages.models import DynamicContentHomeSlider, DynamicContentHomeBody +from organization.pages.models import DynamicContentHomeSlider, DynamicContentHomeBody, JobResponse class DynamicContentHomeSliderForm(autocomplete.FutureModelForm): @@ -14,13 +17,11 @@ class DynamicContentHomeSliderForm(autocomplete.FutureModelForm): content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField( queryset=autocomplete.QuerySetSequence( Article.objects.all(), - # Event.objects.all(), CustomPage.objects.all(), ), required=False, widget=dal_select2_queryset_sequence.widgets.QuerySetSequenceSelect2('dynamic-content-home-slider'), ) - # js = [static("mezzanine/js/admin/dynamic_inline.js")] class Meta: model = DynamicContentHomeSlider @@ -32,7 +33,6 @@ class DynamicContentHomeBodyForm(autocomplete.FutureModelForm): content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField( queryset=autocomplete.QuerySetSequence( Article.objects.all(), - # Event.objects.all(), CustomPage.objects.all(), Brief.objects.all(), ), @@ -43,3 +43,14 @@ class DynamicContentHomeBodyForm(autocomplete.FutureModelForm): class Meta: model = DynamicContentHomeBody fields = ('content_object',) + + +class JobResponseForm(ModelForm): + + def __init__(self, *args, **kwargs): + super(JobResponseForm, self).__init__(*args, **kwargs) + self.fields['job_offer'].widget = forms.HiddenInput() + + class Meta: + model = JobResponse + fields = ['first_name', 'last_name', 'email', 'curriculum_vitae', 'cover_letter', 'job_offer'] diff --git a/app/organization/pages/migrations/0005_auto_20160907_1529.py b/app/organization/pages/migrations/0005_auto_20160907_1529.py new file mode 100644 index 00000000..5a92143e --- /dev/null +++ b/app/organization/pages/migrations/0005_auto_20160907_1529.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-07 13:29 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-pages', '0004_auto_20160907_1153'), + ] + + operations = [ + migrations.AlterField( + model_name='jobresponse', + name='job_offer', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='job_response', to='organization-pages.JobOffer', verbose_name='job offer'), + ), + ] diff --git a/app/organization/pages/migrations/0006_auto_20160908_1032.py b/app/organization/pages/migrations/0006_auto_20160908_1032.py new file mode 100644 index 00000000..4d3a0aae --- /dev/null +++ b/app/organization/pages/migrations/0006_auto_20160908_1032.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-08 08:32 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('sites', '0002_alter_domain_unique'), + ('organization-pages', '0005_auto_20160907_1529'), + ] + + operations = [ + migrations.AddField( + model_name='jobresponse', + name='site', + field=models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'), + preserve_default=False, + ), + migrations.AddField( + model_name='jobresponse', + name='slug', + field=models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL'), + ), + migrations.AddField( + model_name='jobresponse', + name='title', + field=models.CharField(default='job', max_length=500, verbose_name='Title'), + preserve_default=False, + ), + ] diff --git a/app/organization/pages/migrations/0007_auto_20160908_1518.py b/app/organization/pages/migrations/0007_auto_20160908_1518.py new file mode 100644 index 00000000..6a7eb503 --- /dev/null +++ b/app/organization/pages/migrations/0007_auto_20160908_1518.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-08 13:18 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-pages', '0006_auto_20160908_1032'), + ] + + operations = [ + migrations.AlterField( + model_name='jobresponse', + name='cover_letter', + field=models.FileField(max_length=1024, upload_to='job_responses/%Y/%m/%d/', verbose_name='cover letter'), + ), + migrations.AlterField( + model_name='jobresponse', + name='curriculum_vitae', + field=models.FileField(max_length=1024, upload_to='job_responses/%Y/%m/%d/', verbose_name='curriculum vitae'), + ), + ] diff --git a/app/organization/pages/migrations/0008_auto_20160908_1602.py b/app/organization/pages/migrations/0008_auto_20160908_1602.py new file mode 100644 index 00000000..b77b4633 --- /dev/null +++ b/app/organization/pages/migrations/0008_auto_20160908_1602.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-08 14:02 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-pages', '0007_auto_20160908_1518'), + ] + + operations = [ + migrations.RemoveField( + model_name='jobresponse', + name='site', + ), + migrations.RemoveField( + model_name='jobresponse', + name='slug', + ), + migrations.RemoveField( + model_name='jobresponse', + name='title', + ), + ] diff --git a/app/organization/pages/models.py b/app/organization/pages/models.py index d67e40b2..9d1c6b68 100644 --- a/app/organization/pages/models.py +++ b/app/organization/pages/models.py @@ -84,9 +84,9 @@ class JobResponse(models.Model): last_name = models.CharField(max_length=255, null=False, verbose_name=_('last name')) email = models.EmailField(max_length=255, null=False, verbose_name=_('email')) #@TODO validate type format - curriculum_vitae = FileField(_("curriculum_vitae"), max_length=1024, upload_to="job_responses/%Y/%m/%d/") - cover_letter = FileField(_("curriculum_vitae"), max_length=1024, upload_to="job_responses/%Y/%m/%d/") - job_offer = models.ForeignKey("JobOffer", verbose_name=_('job offer'), blank=True, null=True, on_delete=models.SET_NULL) + curriculum_vitae = models.FileField(_("curriculum vitae"), max_length=1024, upload_to="job_responses/%Y/%m/%d/") + cover_letter = models.FileField(_("cover letter"), max_length=1024, upload_to="job_responses/%Y/%m/%d/") + job_offer = models.ForeignKey("JobOffer", verbose_name=_('job offer'), related_name='job_response', blank=True, null=True, on_delete=models.SET_NULL) class Meta: verbose_name = _('job_reponse') @@ -98,9 +98,9 @@ class JobOffer(Displayable, RichText): email = models.EmailField(max_length=255, null=False, verbose_name=_('Email to forward response')) type = models.CharField(blank=True, choices=[('internship', 'internship'), ('job', 'job')], max_length=32, verbose_name='Job offer type') + def get_absolute_url(self): + return reverse("organization-job-offer-detail", kwargs={"slug": self.slug}) + class Meta: verbose_name = _('job offer') verbose_name_plural = _("job offers") - - def get_absolute_url(self): - return reverse("organization-job-offer-detail") diff --git a/app/organization/pages/urls.py b/app/organization/pages/urls.py index 3be6940b..0c626181 100644 --- a/app/organization/pages/urls.py +++ b/app/organization/pages/urls.py @@ -10,7 +10,9 @@ from organization.pages.views import ( DynamicContentHomeSliderView, DynamicContentHomeBodyView, HomeView, - JobOfferDetailView + JobOfferDetailView, + JobOfferListView, + # JobResponseCreate ) _slash = "/" if settings.APPEND_SLASH else "" @@ -20,5 +22,7 @@ urlpatterns = [ url("^dynamic-content-home-slider/$", DynamicContentHomeSliderView.as_view(), name='dynamic-content-home-slider'), url("^dynamic-content-home-body/$", DynamicContentHomeBodyView.as_view(), name='dynamic-content-home-body'), url("^home/$", HomeView.as_view(), name='organization-home'), - url("^job-offer/(?P.*)%s$", JobOfferDetailView.as_view(), name='organization-job-offer-detail'), + url("^job-offer/(?P.*)%s$" % _slash, JobOfferDetailView.as_view(), name='organization-job-offer-detail'), + url("^job-offer/$", JobOfferListView.as_view(), name='organization-job-offer-list'), + #url(r'job-response/add/$', JobResponseCreate.as_view(), name='job-response-add'), ] diff --git a/app/organization/pages/views.py b/app/organization/pages/views.py index 847f770e..e157b88a 100644 --- a/app/organization/pages/views.py +++ b/app/organization/pages/views.py @@ -1,13 +1,17 @@ from django.shortcuts import render from django.views.generic import DetailView, ListView, TemplateView +from django.views.generic.edit import CreateView +from django.contrib import messages from dal import autocomplete from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView +from django.core.urlresolvers import reverse, reverse_lazy +from django.utils.translation import ugettext_lazy as _ # from mezzanine_agenda.models import Event from organization.pages.models import CustomPage from organization.core.views import SlugMixin from organization.magazine.models import Article, Topic, Brief -from organization.pages.models import Home, JobOffer - +from organization.pages.models import Home, JobOffer, JobResponse +from organization.pages.forms import JobResponseForm class HomeView(SlugMixin, ListView): @@ -28,16 +32,63 @@ class HomeView(SlugMixin, ListView): return context -class JobOfferDetailView(SlugMixin, DetailView): +class JobOfferDetailView(CreateView): - model = JobOffer - template_name='pages/job_offer_detail.html' + model = JobResponse + template_name='pages/joboffer/job_offer_detail.html' context_object_name = 'job_offer' + form_class = JobResponseForm def get_context_data(self, **kwargs): context = super(JobOfferDetailView, self).get_context_data(**kwargs) + job_offer = JobOffer.objects.get(slug=self.kwargs['slug']) + if job_offer : + context['job_offer'] = job_offer return context + def get_initial(self): + initial = super(JobOfferDetailView, self).get_initial() + job_offer = JobOffer.objects.get(slug=self.kwargs['slug']) + if job_offer : + initial['job_offer'] = job_offer + return initial + + def get_success_url(self): + return reverse_lazy('organization-job-offer-detail', kwargs={'slug':self.kwargs['slug']}) + + def form_valid(self, form): + messages.info(self.request, _("You have successfully submitted your application.")) + return super(JobOfferDetailView, self).form_valid(form) + + +class JobOfferListView(ListView): + + model = JobOffer + template_name='pages/joboffer/job_offer_list.html' + context_object_name = 'job_offer' + + def get_queryset(self, **kwargs): + return self.model.objects.published() + + def get_context_data(self, **kwargs): + context = super(JobOfferListView, self).get_context_data(**kwargs) + return context + + +# class JobResponseCreate(CreateView): +# +# template_name = 'pages/joboffer/inc/job_response_form.html' +# model = JobResponse +# # form_class = JobResponseForm +# fields = ['first_name', 'last_name', 'email', 'curriculum_vitae', 'cover_letter'] +# # success_url = '/job-offer-success/' +# +# def form_valid(self, form): +# # This method is called when valid form data has been POSTed. +# # It should return an HttpResponse. +# # form.send_email() +# return super(JobResponseView, self).form_valid(form) + class DynamicContentHomeSliderView(Select2QuerySetSequenceView): def get_queryset(self): diff --git a/app/templates/core/inc/messages.html b/app/templates/core/inc/messages.html new file mode 100644 index 00000000..d2bb5061 --- /dev/null +++ b/app/templates/core/inc/messages.html @@ -0,0 +1,7 @@ +{% if messages %} +
    + {% for message in messages %} + {{ message }} + {% endfor %} +
+{% endif %} diff --git a/app/templates/pages/joboffer/inc/job_offer_card.html b/app/templates/pages/joboffer/inc/job_offer_card.html new file mode 100644 index 00000000..11333952 --- /dev/null +++ b/app/templates/pages/joboffer/inc/job_offer_card.html @@ -0,0 +1,4 @@ + +

{{ jo.title }}

+

{{ jo.description|slice:":255" }}

+
diff --git a/app/templates/pages/joboffer/inc/job_response_form.html b/app/templates/pages/joboffer/inc/job_response_form.html new file mode 100644 index 00000000..691c7fcd --- /dev/null +++ b/app/templates/pages/joboffer/inc/job_response_form.html @@ -0,0 +1,4 @@ +
{% csrf_token %} + {{ form.as_p }} + +
diff --git a/app/templates/pages/joboffer/job_offer_detail.html b/app/templates/pages/joboffer/job_offer_detail.html new file mode 100644 index 00000000..660b1009 --- /dev/null +++ b/app/templates/pages/joboffer/job_offer_detail.html @@ -0,0 +1,22 @@ +{% extends "pages/page.html" %} +{% load mezzanine_tags keyword_tags i18n organization_tags %} + + +{% block page_title %} + + {% editable project.title %} +

{{ job_offer.title }}

+ {% endeditable %} + +{% endblock %} + +{% block page_content %} + + {% include "core/inc/messages.html" %} + +

{% trans "Category" %} : {{ job_offer.type }}

+

{{ job_offer.content|richtext_filters|safe }}

+ {% with form as job_offer.job_response %} + {% include "pages/joboffer/inc/job_response_form.html" %} + {% endwith %} +{% endblock %} diff --git a/app/templates/pages/joboffer/job_offer_list.html b/app/templates/pages/joboffer/job_offer_list.html new file mode 100644 index 00000000..b611cc3a --- /dev/null +++ b/app/templates/pages/joboffer/job_offer_list.html @@ -0,0 +1,27 @@ +{% extends "pages/page.html" %} +{% load i18n mezzanine_tags keyword_tags pages_tags organization_tags %} + +{% block meta_title %}{{ job_offer.meta_title }}{% endblock %} + +{% block meta_description %}{% metablock %} +{{ job_offer.description }} +{% endmetablock %}{% endblock %} + +{% block page_class %} + job_offer +{% endblock %} + +{% block page_title %} +

{% trans "Jobs" %}

+{% endblock %} + +{% block page_content %} + {% if job_offer %} + {% for jo in job_offer %} + {% include "pages/joboffer/inc/job_offer_card.html" %} + {% endfor %} + {% else %} +

{% trans "Please come back later. There is no job offer at the moment." %}

+ {% endif %} + +{% endblock %}