Extending Entry model

New in version 0.8.

The Entry model bundled in Zinnia can now be extended and customized.

This feature is useful for who wants to add some fields in the model, or change its behavior. It also allows Zinnia to be a really generic and reusable application.

Why extending ?

Imagine that I find Zinnia really great for my project but some fields or features are missing to be the Weblog app that suits to my project. For example I need to add a custom field linking to an image gallery, two solutions:

  • I search for another Django blogging app fitting my needs.
  • I do a monkey patch, into the Zinnia code base.

These two solutions are really bad.

For the first solution maybe you will not find the desired application and also mean that Zinnia is not a reusable application following the Django’s convention. For the second solution, I don’t think that I need to provide more explanations about the evil side of monkey patching (evolution, reproduction...). That’s why Zinnia provides a third generic solution.

  • Customizing the Entry model noninvasively with the power of class inheritance !

The extension process is done in three main steps:

  1. Write a class containing your customizations.
  2. Register your class into Zinnia to be used.
  3. Update the EntryAdmin class accordingly.

In the suite of this document we will show how to add an image gallery into the Entry model to illustrate the concepts involved. We assume that the pieces of codes written for this document belong in the zinnia_gallery package/application.

Writing model extension

The first step to extend the Entry model is to define a new class inherited from the EntryAbstractClass and add your fields or/and override the inherited methods if needed. So in zinnia_gallery let’s write our new class in a file named entry_gallery.py.

from django.db import models
from zinnia_gallery.models import Gallery
from zinnia.models import EntryAbstractClass

class EntryGallery(EntryAbstractClass):
    gallery = models.ForeignKey(Gallery)

    def __unicode__(self):
        return 'EntryGallery %s' % self.title

    class Meta(EntryAbstractClass.Meta):
        abstract = True

In this code sample, we add a new ForeignKey field named gallery pointing to a Gallery model defined in zinnia_gallery.models and we override the EntryAbstractClass.__unicode__() method.

Note

You have to respect 3 important rules to make extending working :

  1. Do not import the Entry model in your file defining the extended model because it will cause a circular importation.
  2. Do not put your abstract model in a file named models.py, it will not work for a non obvious reason.
  3. Don’t forget to tell that your model is abstract. Otherwise a table will be created and the extending process will not work as expected.

Note

Considerations about the database :

  • If you extend the Entry model after the syncdb command, you have to reset the Zinnia application to reflect your changes.
  • South cannot be used to write migrations to your new model.

See also

Model inheritance for more information about the concepts behind the model inheritence in Django and the limitations.

Registering the extension

Once your extension class is defined you simply have to register it, with the ZINNIA_ENTRY_BASE_MODEL setting in your Django settings. The expected value is a string representing the full Python path to the extented model’s class name. This is the easiest part of the process.

Following our example we must add this line in the project’s settings.

ZINNIA_ENTRY_BASE_MODEL = 'zinnia_gallery.entry_gallery.EntryGallery'

If an error occurs when your new class is imported a warning will be raised and the EntryAbstractClass will be used.

Updating the admin interface

Now we should update the Entry‘s admin class to reflect our changes and use the new fields.

To do that we will write a new admin class inherited from EntryAdmin and use the admin site register/unregister mechanism for using our new class.

In the file zinnia_gallery/admin.py we can write these code lines for adding the gallery field:

from django.contrib import admin
from django.utils.translation import ugettext_lazy as _

from zinnia.models import Entry
from zinnia.admin.entry import EntryAdmin

class EntryGalleryAdmin(EntryAdmin):
  # In our case we put the gallery field
  # into the 'Content' fieldset
  fieldsets = ((_('Content'), {'fields': (
    'title', 'content', 'image', 'status', 'gallery')}),) + \
    EntryAdmin.fieldsets[1:]

# Unregister the default EntryAdmin
# then register the EntryGalleryAdmin class
admin.site.unregister(Entry)
admin.site.register(Entry, EntryGalleryAdmin)

Note that the zinnia_gallery application must be registered in the INSTALLED_APPS setting after the zinnia application for applying the register/unregister mechanism in the admin site.

Now we can easily customize the templates provided by Zinnia to display the gallery field into the Weblog’s pages.

For information you can see another implementation example in the cmsplugin-zinnia package.

Project Versions

Table Of Contents

Previous topic

Permissions

Next topic

Rewriting Entry’s URL

This Page