]> git.parisson.com Git - mezzo.git/commitdiff
Candidacy: done. Need more info about buttons but candidacies can be templated.
authorEmilie <zawadzki@ircam.fr>
Fri, 30 Sep 2016 12:54:40 +0000 (14:54 +0200)
committerEmilie <zawadzki@ircam.fr>
Fri, 30 Sep 2016 12:54:40 +0000 (14:54 +0200)
12 files changed:
app/local_settings.py
app/organization/job/admin.py
app/organization/job/forms.py
app/organization/job/migrations/0004_candidacy.py [new file with mode: 0644]
app/organization/job/migrations/0005_auto_20160930_1254.py [new file with mode: 0644]
app/organization/job/migrations/0006_candidacyimage.py [new file with mode: 0644]
app/organization/job/models.py
app/organization/job/translation.py
app/organization/job/urls.py
app/organization/job/views.py
app/templates/job/candidacy_list.html [new file with mode: 0644]
app/templates/job/inc/candidacy_card.html [new file with mode: 0644]

index 4ddbb1113df67464b738bd8221775ddb6bf3fe32..4f643841e85f7484e775880ddec161cbfa467a04 100644 (file)
@@ -115,7 +115,7 @@ ADMIN_MENU_ORDER = (
                     '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')),
index 9b82ec75f8afe4b240a23992cbb2038773d47b56..31723ac4813358a3b0f504ec5a0b9fe0fbf7bd67 100644 (file)
@@ -2,7 +2,8 @@ from django.contrib import admin
 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):
@@ -16,4 +17,24 @@ class JobOfferAdminDisplayable(BaseTranslationModelAdmin):
     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)
index fca4a411b8bf133b9fa7b966c5bd53fbca9b957c..ed49dc86e877e15f682630715e96c8743a5051bb 100644 (file)
@@ -1,9 +1,13 @@
 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):
@@ -15,3 +19,20 @@ 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__')
diff --git a/app/organization/job/migrations/0004_candidacy.py b/app/organization/job/migrations/0004_candidacy.py
new file mode 100644 (file)
index 0000000..c808c5f
--- /dev/null
@@ -0,0 +1,47 @@
+# -*- 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',
+            },
+        ),
+    ]
diff --git a/app/organization/job/migrations/0005_auto_20160930_1254.py b/app/organization/job/migrations/0005_auto_20160930_1254.py
new file mode 100644 (file)
index 0000000..2faa6b7
--- /dev/null
@@ -0,0 +1,50 @@
+# -*- 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'),
+        ),
+    ]
diff --git a/app/organization/job/migrations/0006_candidacyimage.py b/app/organization/job/migrations/0006_candidacyimage.py
new file mode 100644 (file)
index 0000000..b7ede0f
--- /dev/null
@@ -0,0 +1,33 @@
+# -*- 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',),
+            },
+        ),
+    ]
index 7dfaacaf9f454cdf988b0bb4ac101eef7a59ba19..f445aeaf7589882a040e551f8afa5a342be26e63 100644 (file)
@@ -32,3 +32,39 @@ class JobOffer(Displayable, RichText):
     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)
index e22b59473661e8f0368e7323aff4658790ef3379..e2d6885ea85b91d396c03f2c9c99274eb2d048a3 100644 (file)
@@ -14,3 +14,14 @@ class JobOfferTranslationOptions(TranslationOptions):
 class JobResponseTranslationOptions(TranslationOptions):
 
     pass
+
+@register(Candidacy)
+class JobResponseTranslationOptions(TranslationOptions):
+
+    fields = ('title', 'content', 'text_button', )
+
+
+@register(CandidacyImage)
+class JobResponseTranslationOptions(TranslationOptions):
+
+    pass
index e852861b72ba983928f1fbbac42d0078b4a48584..b91441154a670cd1c65f3869cfd2537a997babdc 100644 (file)
@@ -6,7 +6,7 @@ from django.contrib import admin
 
 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 ""
@@ -14,5 +14,6 @@ _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'),
 ]
index e991cb57cbe7c38033cd29b1b6ed88de71d41e23..1dd4d0f41c26a32f239cf234571e8a85e828224d 100644 (file)
@@ -1,6 +1,8 @@
 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
@@ -15,7 +17,9 @@ from django.utils.translation import ugettext_lazy as _
 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']
@@ -90,3 +94,39 @@ def email_application_notification(request, job_offer, data):
     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
diff --git a/app/templates/job/candidacy_list.html b/app/templates/job/candidacy_list.html
new file mode 100644 (file)
index 0000000..6dc1f4f
--- /dev/null
@@ -0,0 +1,32 @@
+{% 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 %}
diff --git a/app/templates/job/inc/candidacy_card.html b/app/templates/job/inc/candidacy_card.html
new file mode 100644 (file)
index 0000000..4fc0f3e
--- /dev/null
@@ -0,0 +1,19 @@
+{% 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>