PyCon 5 - Florence, May 24, 2014 All you need is… ...Mezzanine!
Aug 19, 2014
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