'shop.DiscountCode',
'shop.Sale',
)),
- (_('Jobs'), ('organization-job.JobOffer',)),
+ (_('Jobs'), ('organization-job.JobOffer','organization-job.Candidacy')),
(_('Festival'), ('organization-festival.Artist',)),
(_('Users'), ('auth.User', 'auth.Group',)),
(_('Site'), ('sites.Site', 'redirects.Redirect', 'conf.Setting')),
from mezzanine.utils.static import static_lazy as static
from copy import deepcopy
from mezzanine.core.admin import *
-from organization.job.models import JobOffer, JobResponse
+from organization.job.models import *
+from organization.job.forms import *
class JobResponseInline(TabularDynamicInlineAdmin):
inlines = [JobResponseInline,]
+class CandidacyImageInline(TabularDynamicInlineAdmin):
+
+ model = CandidacyImage
+
+
+class CandidacyAdmin(admin.ModelAdmin):
+
+ model = Candidacy
+
+
+class CandidacyAdminDisplayable(BaseTranslationModelAdmin,):
+
+ list_display = ('title', 'external_content', 'content_object', )
+ form = CandidacyForm
+ fieldsets = deepcopy(CandidacyAdmin.fieldsets)
+ inlines = [CandidacyImageInline,]
+ exclude = ("short_url", "keywords", "description", "slug", )
+
+
admin.site.register(JobOffer, JobOfferAdminDisplayable)
+admin.site.register(Candidacy, CandidacyAdminDisplayable)
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 organization.job.models import JobResponse
+from organization.job.models import *
+from organization.magazine.models import Article
+from organization.pages.models import CustomPage
+from mezzanine_agenda.models import Event
class JobResponseForm(ModelForm):
class Meta:
model = JobResponse
fields = ['first_name', 'last_name', 'email', 'message', 'curriculum_vitae', 'cover_letter', 'job_offer']
+
+
+class CandidacyForm(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('candidacy-autocomplete'),
+ )
+
+ class Meta:
+ model = Candidacy
+ fields = ('__all__')
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-09-30 10:50
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('contenttypes', '0002_remove_content_type_name'),
+ ('sites', '0002_alter_domain_unique'),
+ ('organization-job', '0003_auto_20160929_1833'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Candidacy',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('keywords_string', models.CharField(blank=True, editable=False, max_length=500)),
+ ('title', models.CharField(max_length=500, verbose_name='Title')),
+ ('slug', 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')),
+ ('_meta_title', models.CharField(blank=True, help_text='Optional title to be used in the HTML title tag. If left blank, the main title field will be used.', max_length=500, null=True, verbose_name='Title')),
+ ('description', models.TextField(blank=True, verbose_name='Description')),
+ ('gen_description', models.BooleanField(default=True, help_text='If checked, the description will be automatically generated from content. Uncheck if you want to manually set a custom description.', verbose_name='Generate description')),
+ ('created', models.DateTimeField(editable=False, null=True)),
+ ('updated', models.DateTimeField(editable=False, null=True)),
+ ('status', models.IntegerField(choices=[(1, 'Draft'), (2, 'Published')], default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status')),
+ ('publish_date', models.DateTimeField(blank=True, db_index=True, help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from')),
+ ('expiry_date', models.DateTimeField(blank=True, help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on')),
+ ('short_url', models.URLField(blank=True, null=True)),
+ ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
+ ('content', mezzanine.core.fields.RichTextField(verbose_name='Content')),
+ ('text_button', models.CharField(blank=True, max_length=150, verbose_name='text button')),
+ ('external_content', models.URLField(blank=True, max_length=1000, verbose_name='external content')),
+ ('object_id', models.PositiveIntegerField(editable=False, null=True, verbose_name='related object')),
+ ('content_type', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='local content')),
+ ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
+ ],
+ options={
+ 'verbose_name': 'candidacy',
+ },
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-09-30 10:54
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organization-job', '0004_candidacy'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='candidacy',
+ options={'verbose_name': 'candidacy', 'verbose_name_plural': 'candidacies'},
+ ),
+ migrations.AddField(
+ model_name='candidacy',
+ name='content_en',
+ field=mezzanine.core.fields.RichTextField(null=True, verbose_name='Content'),
+ ),
+ migrations.AddField(
+ model_name='candidacy',
+ name='content_fr',
+ field=mezzanine.core.fields.RichTextField(null=True, verbose_name='Content'),
+ ),
+ migrations.AddField(
+ model_name='candidacy',
+ name='text_button_en',
+ field=models.CharField(blank=True, max_length=150, null=True, verbose_name='text button'),
+ ),
+ migrations.AddField(
+ model_name='candidacy',
+ name='text_button_fr',
+ field=models.CharField(blank=True, max_length=150, null=True, verbose_name='text button'),
+ ),
+ migrations.AddField(
+ model_name='candidacy',
+ name='title_en',
+ field=models.CharField(max_length=500, null=True, verbose_name='Title'),
+ ),
+ migrations.AddField(
+ model_name='candidacy',
+ name='title_fr',
+ field=models.CharField(max_length=500, null=True, verbose_name='Title'),
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-09-30 12:21
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('organization-job', '0005_auto_20160930_1254'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='CandidacyImage',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('_order', mezzanine.core.fields.OrderField(null=True, verbose_name='Order')),
+ ('title', models.CharField(max_length=1024, verbose_name='title')),
+ ('description', models.TextField(blank=True, verbose_name='description')),
+ ('file', mezzanine.core.fields.FileField(max_length=1024, verbose_name='Image')),
+ ('credits', models.CharField(blank=True, max_length=256, null=True, verbose_name='credits')),
+ ('type', models.CharField(choices=[('logo', 'logo'), ('slider', 'slider'), ('card', 'card'), ('page_slider', 'page - slider'), ('page_featured', 'page - featured')], max_length=64, verbose_name='type')),
+ ('candidacy', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='images', to='organization-job.Candidacy', verbose_name='candidacy')),
+ ],
+ options={
+ 'ordering': ('_order',),
+ },
+ ),
+ ]
class Meta:
verbose_name = _('job offer')
verbose_name_plural = _("job offers")
+
+
+class Candidacy(Displayable, RichText):
+
+ text_button = models.CharField(blank=True, max_length=150, null=False, verbose_name=_('text button'))
+ external_content = models.URLField(blank=True, max_length=1000, null=False, verbose_name=_('external content'))
+
+ # used for autocomplete but hidden in admin
+ content_type = models.ForeignKey(
+ ContentType,
+ verbose_name=_('local content'),
+ null=True,
+ blank=True,
+ editable=False,
+ )
+
+ # used for autocomplete but hidden in admin
+ object_id = models.PositiveIntegerField(
+ verbose_name=_('related object'),
+ null=True,
+ editable=False,
+ )
+
+ content_object = GenericForeignKey('content_type', 'object_id')
+
+ def get_absolute_url(self):
+ return self.external_content
+
+ class Meta:
+ verbose_name = _('candidacy')
+ verbose_name_plural = _("candidacies")
+
+
+class CandidacyImage(Image):
+
+ candidacy = models.ForeignKey(Candidacy, verbose_name=_('candidacy'), related_name='images', blank=True, null=True, on_delete=models.SET_NULL)
class JobResponseTranslationOptions(TranslationOptions):
pass
+
+@register(Candidacy)
+class JobResponseTranslationOptions(TranslationOptions):
+
+ fields = ('title', 'content', 'text_button', )
+
+
+@register(CandidacyImage)
+class JobResponseTranslationOptions(TranslationOptions):
+
+ pass
from mezzanine.core.views import direct_to_template
from mezzanine.conf import settings
-from organization.job.views import JobOfferDetailView, JobOfferListView
+from organization.job.views import *
_slash = "/" if settings.APPEND_SLASH else ""
urlpatterns = [
url("^job-offer/(?P<slug>.*)%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'),
+ url("^candidacies/$", CandidacyListView.as_view(), name='candidacies-list'),
+ url("^candidacy-autocomplete/$", CandidacyAutocomplete.as_view(), name='candidacy-autocomplete'),
]
import os
import mimetypes
import humanize
+from dal import autocomplete
+from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView
from django import forms
from django.shortcuts import redirect
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from mezzanine.conf import settings
-from organization.job.models import JobOffer, JobResponse
+from organization.pages.models import CustomPage
+from organization.magazine.models import Article
+from organization.job.models import *
from organization.job.forms import JobResponseForm
mime_types = ['pdf', 'msword', 'vnd.oasis.opendocument.text', 'vnd.openxmlformats-officedocument.wordprocessingml.document']
msg.send()
return HttpResponse('email_application_notification')
+
+
+class CandidacyListView(ListView):
+
+ model = Candidacy
+ template_name='job/candidacy_list.html'
+ context_object_name = 'candidacy'
+
+ def get_context_data(self, **kwargs):
+ context = super(CandidacyListView, self).get_context_data(**kwargs)
+ return context
+
+
+class CandidacyAutocomplete(Select2QuerySetSequenceView):
+ def get_queryset(self):
+
+ articles = Article.objects.all()
+ custompage = CustomPage.objects.all()
+ events = Event.objects.all()
+
+ if self.q:
+ articles = articles.filter(title__icontains=self.q)
+ custompage = custompage.filter(title__icontains=self.q)
+ events = events.filter(title__icontains=self.q)
+
+ qs = autocomplete.QuerySetSequence(articles, custompage, events )
+
+ if self.q:
+ # This would apply the filter on all the querysets
+ qs = qs.filter(title__icontains=self.q)
+
+ # This will limit each queryset so that they show an equal number
+ # of results.
+ qs = self.mixup_querysets(qs)
+
+ return qs
--- /dev/null
+{% extends "pages/page.html" %}
+{% load i18n mezzanine_tags keyword_tags pages_tags organization_tags %}
+
+{% block meta_title %}{% trans "Candidacies" %}{% endblock %}
+
+{% block meta_description %}{% metablock %}
+{{ candidacy.description }}
+{% endmetablock %}{% endblock %}
+
+{% block page_class %}
+ candidacy
+{% endblock %}
+
+{% block page_title %}
+ <h1 class="dotted">{% trans "Candidacies" %}</h1>
+{% endblock %}
+
+{% block page_content %}
+
+ {% if candidacy %}
+
+ {% for content in candidacy %}
+ {% include "job/inc/candidacy_card.html" %}
+ {% endfor %}
+
+ {% else %}
+
+ <p>{% trans "Please come back later. There is no candidacy at the moment." %}</p>
+
+ {% endif %}
+
+{% endblock %}
--- /dev/null
+{% load i18n mezzanine_tags keyword_tags pages_tags organization_tags %}
+<div>
+ {% with content.images.all|get_type:'card' as images %}
+ {% if images %}
+ <img src="{{ MEDIA_URL }}{% thumbnail images.first 150 150 %}" alt="{{ content.title }}">
+ {% endif %}
+ {% endwith %}
+ <h2>{{ content.title }}</h2>
+ <div>
+ <strong>{{ content.publish_date|date:"DATE_FORMAT" }}</strong><br />
+ {{ content.description|slice:":500" }}
+ </div>
+ <br>
+ {% if content.external_content %}
+ <a class="" href="{{ content.external_content }}" title="{{ content.text_button }}">{{ content.text_button }}</a>
+ {% elif content.content_object %}
+ <a class="" href="{{ content.content_object.get_absolute_url }}" title="{{ content.text_button }}">{{ content.text_button }}</a>
+ {% endif %}
+</div>