mezzanine
mezzanine copied to clipboard
Apply Mezzanine's Dynamic inline to Django's Stacked/Generic inlines
I'm running off of head which looks to be version 0.11. I've created a new page type that in the admin uses inlined objects in the admin. The mezzanine code removes all of the inline forms that were added but doesn't put new ones back. Nor does there seem to be a method for adding new ones. Below is my code.
models.py file
from django.conf import settings
from django.db import models
from mezzanine.core.models import RichText
from mezzanine.pages.models import Page
# Create your models here.
class TemplatedPage(Page):
template = models.CharField(max_length=512, verbose_name="Template Name",
help_text="The name of the template to use when rendering this page.",
choices=getattr(settings, "EXTENDED_PAGES_TEMPLATES", []))
class Meta:
verbose_name = "Templated Page"
verbose_name_plural = "Templated Pages"
class PageSection(RichText):
page = models.ForeignKey(TemplatedPage, related_name="sections")
name = models.CharField(max_length=32, verbose_name="Name", help_text="Name of Page Section Content.")
order = models.PositiveSmallIntegerField(choices=[(x,x) for x in range(50)], default=0, verbose_name="Order", help_text="If you have multiple sections with the same name this helps order them.")
class Meta:
verbose_name = "Page Section"
verbose_name_plural = "Page Sections"
admin.py file
from copy import deepcopy
from django.contrib import admin
from mezzanine.pages.admin import PageAdmin
from .models import PageSection, TemplatedPage
class PageSectionInline(admin.StackedInline):
model = PageSection
#fields = ("order", "content")
#extra = 2
TEMPLATED_PAGE_FIELDSETS = deepcopy(PageAdmin.fieldsets)
TEMPLATED_PAGE_FIELDSETS[0][1]['fields'].insert(2,"template")
class TemplatedPageAdmin(PageAdmin):
inlines = (PageSectionInline,)
fieldsets = TEMPLATED_PAGE_FIELDSETS
admin.site.register(TemplatedPage, TemplatedPageAdmin)
If the problem isn't caused by mezzanine but is instead something I've done wrong please let me know.
The problem seems to stem from core/templates/admin/base_site.html:L194 removing the inlines without there being a way to add ones back.
Couple of things:
Firstly just double check that it's not a particular issue with your browser - have a look at an existing record with dynamic inlines on the demo site (http://mezzanine.jupo.org/admin/forms/form/3/ user/pass: demo/demo) which is running off the same 0.11 code base. You should see a link on the right-hand side under the dynamic inlines (form fields in this case) that says "Add another". If that works for you then you can rule out it being a Mezzanine bug specific to your browser.
Secondly I believe your admin class PageSectionInline should inherit from mezzanine.core.admin.DynamicInlineAdmin - again take a look at the built-in example mezzanine.forms.models.Form which makes use of all the dynamic inline functionality, taking note of the admin classes it uses to set everything up.
Hope this helps. Let me know how you go.
Yep you are right. I guess I didn't see in the documentation that it needed to inherit from mezzanine.core.admin.DynamicInlineAdmin. Once I did that it worked. Thanks for clearing that up for me.
Are there plans to make a version that inherits from StackedInline?
Glad you got it working. I actually don't think the dynamic inlines are documented anywhere to be honest.
I hadn't planned to add a StackedInline version but that is a great idea. If you'd like to set that up I'd be happy to pull it in.
I'd imagine the DynamicInlineAdmin as it stands now would no longer inherit from Tabular inline, ad we'd end up with something like:
DynamicInlineAdmin becomes: BaseDynamicInlineAdmin(object)
then add:
TabularDynamicInlineAdmin(BaseDynamicInlineAdmin, TabularInline): pass StackedDynamicInlineAdmin(BaseDynamicInlineAdmin, StackedInline): pass
I might have gotten some of those names wrong, I didn't look them up. We'd then need to update any references to the old name - I believe it's just the form admin I referred to earlier that's using this.
What do you think?
I'm under a deadline right now but I'll look at doing it once that pressure is off.
On Tue, May 3, 2011 at 3:14 PM, stephenmcd < [email protected]>wrote:
Glad you got it working. I actually don't think the dynamic inlines are documented anywhere to be honest.
I hadn't planned to add a StackedInline version but that is a great idea. If you'd like to set that up I'd be happy to pull it in.
I'd imagine the DynamicInlineAdmin as it stands now would no longer inherit from Tabular inline, ad we'd end up with something like:
DynamicInlineAdmin becomes: BaseDynamicInlineAdmin(object)
then add:
TabularDynamicInlineAdmin(BaseDynamicInlineAdmin, TabularInline): pass StackedDynamicInlineAdmin(BaseDynamicInlineAdmin, StackedInline): pass
I might have gotten some of those names wrong, I didn't look them up. We'd then need to update any references to the old name - I believe it's just the form admin I referred to earlier that's using this.
What do you think?
Reply to this email directly or view it on GitHub: https://github.com/stephenmcd/mezzanine/issues/62#comment_1096468
No worries - I'm under the pump here too but if I get a chance before you I will do it anyway :-)
Hey I checked in the initial version of this:
https://github.com/stephenmcd/mezzanine/commit/42ff3b377be5b50692eb59da14925016f7a03b86
Stacked doesn't quite work yet - some of the Javascript I have in mezzanine/core/templates/admin/base_site.html conflicts with it. If you get a chance to take this any further let me know and we can talk through it.
Cheers, Steve
Not sure if this is entirely related but I have never been able to get StackedInlines to work with Mezzanine and think I finally tracked down the issue. I'm wondering if its related to this. Anyways you can view the change here: https://bitbucket.org/joshcartme/mezzanine/changeset/a9e1cfa42cdd
Thanks Josh that's great - you've resolved the issue I mentioned in my last comment here.
So StackedDynamicInlineAdmin is partially working now as of:
https://github.com/stephenmcd/mezzanine/commit/6e75c84b2f1b31770e4406facb55db392ca88d79
Drag and drop ordering doesn't work yet so I've simply hidden the widget. More work is needed - I guess the drag and drop widget should somehow go into the header above each inline. It also doesn't work at without Grappelli installed as there's no easy way to target the stacked inlines with jQuery.
Given that I'll leave this issue open for now.
The script mentioned earlier is breaking StackedInlines in a separate app for me. The insertion of extra rows through JS gets busted.
If that script is still somehow needed in Mezzanine it ought to be moved or scoped in a way that it does not conflict with other apps.
https://github.com/stephenmcd/mezzanine/blob/master/mezzanine/core/static/mezzanine/js/admin/navigation.js#L91
I've got a couple of projects where I'd love to get jQuery ordering happening. @stephenmcd are you able to point me in the right direction and I can take a look?
@nlh-kabu - take a look at the models in mezzanine.forms and how they're built, as well as their related admin classes. This thread will make a lot more sense with that background.
If you're simply looking for drag/drop ordering with jQuery then it already exists as per the mezzanine.forms examples, it's probably just not well documented.
Was there ever a resolution to this? From recollection Grappelli-vanilla seems to convert admin.StackedInline into dynamic versions. I'd like to use mezzanine with some other third-party apps and don't want to have to monkey patch their code to get dynamic versions.
Yep this really broke third-party apps. Watch this example:
class PersonMembershipInline(admin.TabularInline):
model = PersonMembership
extra = 1
class GroupAdmin(admin.ModelAdmin):
inlines = [
PersonMembershipInline,
]
class Group(models.Model):
members = models.ManyToManyField('Person', blank=True, through='PersonMembership')
In the group admin there are TWO empty rows (instead of one), but only one works on save and TabularDynamicInlineAdmin doens't save your life too. Autocomplete fields in inlines are totally useless, they works only edit related rows.
I used the same code in grappelli and there everything works (I'm also able to add extra records dynamically).
I have the same problem.
My solution is use TabularDynamicInlineAdmin from mezzanine.core.admin
Been struggling using the drag and drop sort on stacked inlines for a while, and I was able to get the sort to save by monkeypatching dynamic_inline.js. Replaced line 41:
var orderSelector = window.__grappelli_installed ? '._order input' : '.field-_order input';
with
var orderSelector = '.field-_order input, ._order input';
Looks like the stacked inline isn't being classed like grappelli expects, so I just check for both.