All you need is...Mezzanine!

Post on 19-Aug-2014

120 views 1 download

Tags:

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 of All you need is...Mezzanine!

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

http://mezzanine.jupo.org/

http://mezzanine.jupo.org/

http://mezzanine.jupo.org/

Batteries Included

http://mezzanine.jupo.org/

Batteries Included

- 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.

Thank you! ….questions?

Talk Mezzanine Project codehttps://github.com/simodalla/mezzanine_talk_polls