1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
=====================
Extending Entry model
=====================
.. module:: zinnia.models
The :class:`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 allows Zinnia to be a really generic
and reusable application.
Imagine that I find Zinnia really great, but that is misses some fields
or features to be the blog app that I need for my Django project.
For example I need to add a custom field linking to an image gallery,
2 solutions:
* I search for another Django blogging app fitting my needs.
* I make a monkey patch, but I won't be able to upgrade to future releases.
These 2 solutions are really bad, that's why Zinnia provides
a third solution.
* Customizing the model noninvasively with the power of inheritance.
How do we do that?
In fact, simply by creating an abstract model inherited from
:class:`EntryBaseModel`, adding fields or/and overriding his methods, and
registering it with the :setting:`ZINNIA_ENTRY_BASE_MODEL` setting in your
project.
Example for adding a gallery field. ::
from django.db import models
from mygalleryapp.models import Gallery
from zinnia.models import EntryAbstractClass
class EntryGallery(EntryAbstractClass):
gallery = models.ForeignKey(Gallery)
class Meta:
abstract = True
Now you register the :class:`EntryGallery` model like this in your
project's settings. ::
ZINNIA_ENTRY_BASE_MODEL = 'appname.custom_entry.EntryGallery'
Finally extend the entry's admin class to show your custom field. ::
from django.contrib import admin
from zinnia.models import Entry
from zinnia.admin.entry import EntryAdmin
from django.utils.translation import ugettext_lazy as _
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:]
admin.site.unregister(Entry)
admin.site.register(Entry, EntryGalleryAdmin)
You can see another example in the files :file:`zinnia/plugins/placeholder.py`
and :file:`zinnia/plugins/admin.py`.
.. note:: You have to respect **4 important rules** :
#. Do not import the Entry model in your file defining the
extended model because it will cause a circular importation.
#. Do not put your abstract model in a file named models.py,
it will not work for a non obvious reason.
#. 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.
#. If you extend the Entry model after the syncdb command, you
will have to reset the Zinnia application to reflect your
changes.
|