all you need is...mezzanine!
DESCRIPTION
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.TRANSCRIPT
PyCon 5 - Florence, May 24, 2014
All you need is…
...Mezzanine!
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!
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 publishinto official government web
site
OpenPa by Mezzaninehttps://www2.comune.zolapredosa.bo.it
- Ecommerce: cartridge.jupo.org - Forum: drum.jupo.org- Themes: mezzathe.me
~ 70 Packages: https://www.djangopackages.com/grids/g/mezzanine/
EXTRA Batteries Included
Bootstrap (into an virtualenv)# Install from Pypi(venv)$ pip install mezzanine [south django-debug-toolbar]
# Create a project(venv)$ mezzanine-project mysite(venv)$ cd mysite
# Create a database(venv)$ python manage.py createdb
# Apply default migrations(venv)$ python manage.py migrate
# Run the webserver(venv)$ python manage.py runserver
Et voilà...
User
User (backoffice)
User (backoffice)
http://blog.jupo.org/2014/04/19/mezzanine-3.1-for-workgroups/
Growth of Mezzanine has been consistent
Developer... “and now???”
“Mantra for working with Mezzanine:
Mezzanine is Just Django”
Ken Bolton, long-time Mezzanine contributor.
Creating Custom Content Types
from django.db import modelsfrom 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
Admin Custom Content Typesfrom copy import deepcopyfrom django.contrib import adminfrom mezzanine.core.admin import (
TabularDynamicInlineAdmin)from mezzanine.pages.admin import PageAdminfrom .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
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
Page Processor
http://mezzanine.jupo.org/docs/content-architecture.html#page-processors
from django.shortcuts import get_object_or_404from mezzanine.pages.page_processors import processor_forfrom .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
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.
Integrating Third-party Apps
http://mezzanine.jupo.org/docs/content-architecture.html#integrating-third-party-apps-with-pages
Other requirement is pages in Mezzanine’s navigation to point to the urlpatterns for these regular Django apps. Implementing this simply requires creating a page (RichTextPage, Link..) in the admin, with a URL matching a pattern used by the application.
More information? Need help?Documentationhttp://mezzanine.jupo.org/@stephen_mcd PyCon APAC keynote
Source Codehttps://github.com/stephenmcd/mezzanine
Mailing list https://groups.google.com/forum/#!forum/mezzanine-users
Issues trackerhttps://github.com/stephenmcd/mezzanine/issues
Thank you! ….questions?
Talk Mezzanine Project codehttps://github.com/simodalla/mezzanine_talk_polls