1 of 39

Spicing up Django:�Intro to Mezzanine CMS

Ed Rivas

@je92rivas

2 of 39

Mezzanine CMS

3 of 39

Mezzanine trivia

  • Created by Stephen McDonald
  • 7 years under active development
  • 275+ contributors
  • Helpful community
  • Well documented
  • Variety of third-party packages

4 of 39

Mezzanine is...

  • A content-oriented sites platform
  • Batteries included
  • Useful mixins, helpers, etc
  • Power to the developer

5 of 39

Above everything else:

Mezzanine is just Django

6 of 39

Let’s get started!

7 of 39

Quickstart

  • pip install mezzanine
  • mezzanine-project my-project
  • python manage.py createdb
  • python manage.py runserver

8 of 39

9 of 39

Write your own app

10 of 39

The polls app

  • Models: Polls + Choices
  • Editable via admin site
  • Has a “list” and “detail” view
  • Handles form input (voting)

11 of 39

Installing apps

  • Add your app to INSTALLED_APPS
  • Wire up your urlconf
  • Run migrations

Like you do in any Django project

12 of 39

13 of 39

14 of 39

Spicing it up

15 of 39

Some new requirements

  • We want a publishing workflow
  • Most recent polls first
  • Slugs instead of PKs in URLs
  • We want Choices to be sortable

16 of 39

The original model

# models.py

class Poll(models.Model):� question = models.CharField(max_length=200)

17 of 39

The Displayable model

  • Base for all public-facing content pieces in Mezzanine
  • Adds Draft / Published status
  • Allows for scheduled publishing
  • Can auto-generate slugs
  • Comes with sidekick admin class and manager

18 of 39

The Displayable fields

  • title
  • meta_title
  • slug (auto / customizable)
  • description
  • publish_date
  • status
  • more...

19 of 39

The Displayable model

# models.py

from mezzanine.core.models import Displayable��class Poll(Displayable):� pass� # Yep, that’s it

20 of 39

The original admin

# admin.py

class PollAdmin(admin.ModelAdmin):� fields = ['question']� inlines = [ChoiceInline]� list_display = ('question',)� search_fields = ['question']

21 of 39

22 of 39

The Displayable admin

# admin.py

from mezzanine.core.admin import DisplayableAdmin��class PollAdmin(DisplayableAdmin):� inlines = [ChoiceInline]

23 of 39

24 of 39

25 of 39

The published manager

# views.py

class IndexView(generic.ListView):� template_name = 'polls/index.html'� context_object_name = 'latest_poll_list'�� def get_queryset(self):� return (Poll.objects.published()� .order_by("-publish_date")[:5])

26 of 39

The published manager

Resulting view content:

27 of 39

The Orderable model

  • Ideal for sortable inlines.
  • Comes in both Stacked and Tabular varieties.
  • Supports drag-n-drop sorting.
  • Supports dynamic creation of more inline forms.

28 of 39

The Orderable model

# models.py

from mezzanine.core.models import Orderable��class Choice(Orderable):� poll = models.ForeignKey(Poll)� choice_text = models.CharField()� votes = models.IntegerField(default=0)

29 of 39

Dynamic inlines

# admin.py

from mezzanine.core.admin import TabularDynamicInlineAdmin��class ChoiceInline(TabularDynamicInlineAdmin):� model = Choice� readonly_fields = ('votes',)

30 of 39

31 of 39

Templates

32 of 39

33 of 39

Templates

{% extends 'base.html' %}��{% block title %}{{ poll.title }}{% endblock %}��{% block main %}�...�{% endblock %}

34 of 39

35 of 39

Review

36 of 39

Writing Mezzanine apps

  • Models: Inherit from Displayable
  • Inlines: Inherit from Orderable
  • Queries: Use objects.published()
  • Templates: Extend Mezzanine’s blocks.

37 of 39

Not pictured

  • Custom page types
  • File management
  • Automated deployments
  • Page processors
  • eCommerce
  • WYSIWYG editor (swappable)
  • User-editable settings

38 of 39

Further reading

  • Mezzanine’s Content Architecture
  • Community blogs
  • Mezzanine’s blog app

39 of 39

Thanks!

Ed Rivas

@je92rivas

bit.ly/mezz-polls

github.com/jerivas/mezzanine-poll-demo