Upgrade to Pro — share decks privately, control downloads, hide ads and more …

All you need is...Mezzanine (and a good content API)!

All you need is...Mezzanine (and a good content API)!

Slides of talk by Simone Dalla on Mezzanine at DjangoVillage, Orvieto, Italy, June 2014.

Mezzanine is an open source content management platform built using Django Framework.

Simone Dalla

June 18, 2014
Tweet

More Decks by Simone Dalla

Other Decks in Programming

Transcript

  1. 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! !
  2. 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
  3. - Ecommerce: cartridge.jupo.org - Forum: drum.jupo.org - Themes: mezzathe.me !

    ~ 70 Packages: https:// www.djangopackages.com/ grids/g/mezzanine/ EXTRA Batteries Included
  4. 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
  5. “Mantra for working with Mezzanine: Mezzanine is Just Django” !

    Ken Bolton, long-time Mezzanine contributor.
  6. Mezzanine Content API mezzanine.core.models.SiteRelated - Contains a related django.contrib.sites.models.Site field.

    ! mezzanine.core.models.Slugged - Implements a title and URL (slug). ! mezzanine.core.models.MetaData - Provides SEO meta data, such as title, description and keywords. ! mezzanine.core.models.TimeStamped - Provides created and updated timestamps. ! mezzanine.core.models.Ownable - Contains a related user field, suitable for content owned by specific authors. ! mezzanine.core.models.RichText - Provides a WYSIWYG editable field. ! mezzanine.core.models.Orderable - Used to implement drag/drop ordering of content, whether out of the box as Django admin inlines, or custom such as Mezzanine’s page tree. mezzanine/core/models.py Abstract Models http://mezzanine.jupo.org/docs/content-architecture.html#content- architecture
  7. Mezzanine Content API ! ! ! mezzanine.core.models.Displayable - Combines all

    the models in previous page, then implements publishing features, such as status and dates. ! mezzanine.core.pages.Page - Default Page subclass, providing a WYSIWYG editable field. http://mezzanine.jupo.org/docs/content-architecture.html#content-architecture mezzanine/core/models.py mezzanine/pages/models.py Abstract Model
  8. Mezzanine Content API mezzanine.blog.models.BlogPost - Blog posts that subclass Displayable

    as they’re not part of the site’s navigation. ! mezzanine.pages.models.RichTextPage - Default Page subclass, providing a WYSIWYG editable field. ! mezzanine.pages.models.Link - Page subclass for links pointing to other URLs. ! mezzanine.forms.models.Form - Page subclass for building forms. ! mezzanine.galleries.models.Gallery - Page subclass for building image gallery pages. http://mezzanine.jupo.org/docs/content-architecture.html#content-architecture mezzanine/pages/models.py
  9. 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 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
  10. Admin Custom Content Types from copy import deep copy 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",)}),) ! classChoiceInline(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
  11. 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.html
  12. 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/templates/poll.html polls/page_processors.py
  13. 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.
  14. 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.
  15. More information? Need help? Documentation http://mezzanine.jupo.org/ @stephen_mcd PyCon APAC keynote

    ! Source Code https://github.com/stephenmcd/mezzanine ! Mailing list https://groups.google.com/forum/#!forum/mezzanine-users ! Issues tracker https://github.com/stephenmcd/mezzanine/issues