Slides of talk by Simone Dalla on Mezzanine at Pycon 5, Florence, Italy, May 2014.
Mezzanine is an open source content management platform built using Django Framework.
1. PyCon 5 - Florence, May 24, 2014
All you need is…
...Mezzanine!
2. Simone Dalla @simodalla
CI[T]O of Comune di Zola Predosa (Bologna, IT)
Pythonista and Django programmer.
I use Python into my work environment for.....
ALL!
3. Problem
Respect of Italy’s decree-law:
“Amministrazione Trasparente, Pubblicazioni ai sensi del Decreto Legislativo
14 marzo 2013, n. 33. Riordino della disciplina riguardante gli obblighi di
pubblicità, trasparenza e diffusione di informazioni da parte delle pubbliche
amministrazioni. (GU n.80 del 5-4-2013)”
≃ 250 obligation to publish
into official government web
site
17. “Mantra for working with
Mezzanine:
Mezzanine is Just Django”
Ken Bolton, long-time Mezzanine contributor.
18. Creating Custom Content Types
from django.db import models
from mezzanine.pages.models import Page
# The members of Page will be inherited by the Poll
# model, such as title, slug, etc. For polls we can use
# the title field to store the poll’s question. For our
# model definition, we just add any extra fields that
# aren't part of the Page model, in this case, date of
# publication.
class Poll(Page):
# question = models.CharField(max_length=200)
pub_date = models.DateTimeField("Date published")
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
https://docs.djangoproject.com/en/1.
6/intro/tutorial01/#creating-models
http://mezzanine.jupo.org/docs/content-architecture.
html#creating-custom-content-types
(venv)$ python manage.py startapp polls
polls/models.py
19. Admin Custom Content Types
from copy import deepcopy
from django.contrib import admin
from mezzanine.core.admin import (
TabularDynamicInlineAdmin)
from mezzanine.pages.admin import PageAdmin
from .models import Poll, Choice
poll_extra_fieldsets = (
(None, {"fields": ("pub_date",)}),)
class ChoiceInline(TabularDynamicInlineAdmin):
model = Choice
class PollAdmin(PageAdmin):
inlines = (ChoiceInline,)
fieldsets = (deepcopy(PageAdmin.fieldsets) +
poll_extra_fieldsets)
admin.site.register(Poll, PollAdmin)
https://docs.djangoproject.com/en/1.
6/intro/tutorial02/#adding-related-objects
http://mezzanine.jupo.org/docs/content-architecture.
html#creating-custom-content-types
polls/admin.py
20. Displaying Custom Content Types
>>> Poll.objects.create(title="What's your favourite program language?", pub_date=now())
<Poll: What's your favourite program language?>
>>> page = Page.objects.create(title="What's your favourite program language?")
>>> page
<Page: What's your favourite program language?>
>>> page.poll
<Poll: What's your favourite program language?>
>>> page.get_content_model()
<Poll: What’s your favourite program language>
http://mezzanine.jupo.org/docs/content-architecture.html#displaying-custom-content-types
{% extends "pages/page.html" %}
{% load mezzanine_tags %}
{% block title %}
{% editable page.poll.title %}{{ page.poll.title }}{% endeditable %}
{% endblock %}
{% block main %}
{{ block.super }}
<p>Published at {{ page.poll.pub_date }}</p>
<ul>
{% for choice in page.poll.choice_set.all %}
<li>{% editable choice.choice_text %}{{ choice.choice_text }}{% endeditable %} n. votes: {{ choice.votes }}</li>
{% endfor %}
</ul>
{% endblock %}
polls/templates/poll.py
21. Page Processor
http://mezzanine.jupo.org/docs/content-architecture.html#page-processors
from django.shortcuts import get_object_or_404
from mezzanine.pages.page_processors import processor_for
from .models import Poll, Choice
@processor_for(Poll)
def author_form(request, page):
if request.method == "POST":
p = get_object_or_404(Poll, pk=page.poll.id)
try:
selected_choice = p.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return {'error_message': "You didn't select a choice."}
else:
selected_choice.votes += 1
selected_choice.save()
return {'success_message': "Thank you for your vote."}
<h2>Vote!!!</h2>
{% if error_message %}<div class="alert alert-danger">{{ error_message }}</div>{% endif %}
{% if success_message %}<div class="alert alert-success">{{ success_message }}</div>{% endif %}
<form action="." method="post">
{% csrf_token %}
{% for choice in page.poll.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
polls/page_processors.py
polls/templates/poll.py
22. Integrating Third-party Apps
http://mezzanine.jupo.org/docs/content-architecture.html#integrating-third-party-apps-with-pages
# MEZZANINE'S URLS
# ----------------
# ADD YOUR OWN URLPATTERNS *ABOVE* THE LINE BELOW. ``mezzanine.urls`` INCLUDES
# A *CATCH ALL* PATTERN FOR PAGES, SO URLPATTERNS ADDED BELOW ``mezzanine.
urls``
# WILL NEVER BE MATCHED!
url(r'^dj_polls/', include('dj_polls.urls', namespace='polls')),
# If you'd like more granular control over the patterns in ``mezzanine.urls``, go right ahead
# and take the parts you want from it, and use them directly below instead of using
# ``mezzanine.urls``.
("^", include("mezzanine.urls")),
Our “regoular third-party” Django app to integrate. Polls apps of official
Django tutorial named here “dj_polls”.
https://docs.djangoproject.com/en/1.6/intro/tutorial01/
Polls “Mezzanine” app developed earlier for custom types.