Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django-CMS foreign key on pages showing published and draft pages

I have recently upgraded from Django-CMS 2.3.5 to 2.4.1.

Previously I had a model like so:

from django.db import models
from cms.models.pagemodel import Page

class MyModel(models.Model):
    my_page = models.ForeignKey(Page)

In the admin, this would nicely allow me to choose a page to associate with MyModel.

Now that I have upgraded, and gone through and pressed "publish draft" on all my pages, the same admin page shows two copies of each page in its selection box - one published and one draft.

Some further investigation has uncovered that the teaser plugin has the following added in its definition to deal with this:

    page_link = models.ForeignKey(Page,
        limit_choices_to={'publisher_is_draft': True},
        ...)

Similarly, I used to be able to look up page URLs in my views like so:

Page.objects.get(reverse_id='update').get_absolute_url()

But now I have to use:

Page.objects.get(reverse_id='update', publisher_is_draft=False).get_absolute_url()

This seems a bit ugly.

Are the limit_choices_to and the extra field in the get now necessary? Or is there a cleaner way to only see published pages? (e.g. I notice that other cms plugins, e.g. link, picture, use foreign keys without a limit_choices_to argument.)

like image 623
Racing Tadpole Avatar asked May 26 '13 23:05

Racing Tadpole


1 Answers

For better handling of foreign keys to cms pages you need to use PageField instead of ForeignKey

https://django-cms.readthedocs.org/en/2.4.3/extending_cms/fields.html

from django.db import models
from cms.models.fields import PageField

class MyModel(models.Model):
    my_page = PageField()

When you want to get url for a page by it's reverse_id you need to use the following

Page.objects.public().get(reverse_id='update').get_absolute_url()
like image 132
Venelin Stoykov Avatar answered Oct 10 '22 20:10

Venelin Stoykov