Wagtail Pages using Proxy models

227 views
Skip to first unread message

Nick Barreto

unread,
Jun 6, 2016, 6:24:58 AM6/6/16
to Wagtail support
Hello everyone,

I'm creating some new page types which are actually identical to models I already have, but for a different root domain which will have a different design and branding. 

It seemed to me that proxy models would be the ideal solution, as I could set a different template to the new page models while keeping the database clean. However, when I create a new page using a proxy model, the Wagtail admin doesn't seem to differentiate in any way between the proxy and the parent model, and despite using 
template ='myapp/other_template.html
or 
def get_template
in the proxy model, pages created using the proxy model are still displaying with the parent's template, and overall simply appear to be of the parent model type, rather than the proxy. 

Now I am fairly new to Django so may be misunderstanding the usage of a proxy model – is this the correct behaviour? Am I setting it up incorrectly? Do I need to define something further in the proxy model for it to use the other template?

I suppose another approach would be to not have proxy templates, but instead use a get_template method as described in the docs which tests for which type of parent a page has, and select the appropriate template that way. Is this a better implementation?

Thanks,
-Nick

Brett Grace

unread,
Jun 7, 2016, 12:39:52 AM6/7/16
to Wagtail support
I believe this is probably what is biting you:

There is no way to have Django return, say, a MyPerson object whenever you query for Person objects. A queryset for Person objects will return those types of objects. The whole point of proxy objects is that code relying on the original Person will use those and your own code can use the extensions you included (that no other code is relying on anyway). It is not a way to replace the Person (or any other) model everywhere with something of your own creation.

- https://docs.djangoproject.com/en/1.9/topics/db/models/#querysets-still-return-the-model-that-was-requested

If you need the same models, working for different Site hierarchies, you might try creating a mixin that overrides get_template so that the search path for the template includes a site-based path.

Nick Barreto

unread,
Jun 7, 2016, 6:54:07 AM6/7/16
to Wagtail support
Yep, that is most probably it. I guess it is related to how the Wagtail Admin handles page creation? I create a page with the new, proxy model, but instead it calls the model parent for the database creation etc? 

Anyway, I am using def get_template and testing if a page has a particular page type in its ancestry, which in our hierarchies will definitively tell you which is which. It's working as expected.

Thanks for the help, Brett!

Cheers,
-Nick

Nick Barreto

unread,
Jun 7, 2016, 6:56:32 AM6/7/16
to Wagtail support
For future reference, if anyone is attempting to do something similar, that test looks like this:


def get_template(self, request):
OtherPageTest = OtherHomePage.objects.ancestor_of(self)
if OtherPageTest:
return 'otherpage/page_template.html'

return 'myapp/page_template.html'

Cheers,
-Nick

Matthew Westcott

unread,
Jun 7, 2016, 7:02:56 AM6/7/16
to wag...@googlegroups.com
I guess this is where this pull request would come in...
https://github.com/torchbox/wagtail/pull/1736
Looks like it'll need some thorough tests / docs before it's ready to be merged, though.

Cheers,
- Matt

Nick Barreto

unread,
Jun 7, 2016, 7:40:26 AM6/7/16
to wag...@googlegroups.com
Interesting. Glad to see it's being worked on! The wagtail community is awesome :D

-Nick 

Nick Barreto
Co-founder & Technology Director
CANELO | www.canelo.co
@canelo_co | @nickbarreto

--
You received this message because you are subscribed to a topic in the Google Groups "Wagtail support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/wagtail/bIVzOEuVJMI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to wagtail+u...@googlegroups.com.
To post to this group, send an email to wag...@googlegroups.com.
Visit this group at https://groups.google.com/group/wagtail.
To view this discussion on the web, visit https://groups.google.com/d/msgid/wagtail/3732153B-6017-4DF1-881E-DE2E7EC8F5F7%40torchbox.com.
For more options, visit https://groups.google.com/d/optout.

Brett Grace

unread,
Jun 7, 2016, 11:08:41 AM6/7/16
to Wagtail support
Instead of doing an ancestor check, you can switch on the Site explicitly (request.site). That way your test isn't tied to a specific model. Maybe something like this (untested, not production quality pseudo-code):

class HasSiteSpecificTemplate:

    def get_template(self, request, *args, **kwargs):
        default_template = super(HasSiteSpecificTemplate, self).get_template(request, *args, **kwargs)
        site_component = slugify(request.site.name)
        site_specific_template = path.join(site_component, default_template)

        return select_template(site_specific_template, default_template)

Mix this into your Page models and then you don't have to hard code the template path into each model, since Wagtail already computes this for you. If your templates directory doesn't contain a site-specific variant, you fall back to the default.

Just an idea.

Nick Barreto

unread,
Jun 7, 2016, 11:21:45 AM6/7/16
to wag...@googlegroups.com
That is a good idea, more scalable. I'll take a look and possibly implement in the near future. 

Thanks Brett.

Cheers,
-Nick

Nick Barreto
Co-founder & Technology Director
CANELO | www.canelo.co
@canelo_co | @nickbarreto

--
You received this message because you are subscribed to a topic in the Google Groups "Wagtail support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/wagtail/bIVzOEuVJMI/unsubscribe.
To unsubscribe from this group and all its topics, send an email to wagtail+u...@googlegroups.com.
To post to this group, send email to wag...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages