Reputation: 5837
mostly I use flatpages for one site (from sites framework). How can I mark existing site default for all created flatpages? It is waste of time every time to choose same site for every page created. Is there any way to override this in models or save method?
Upvotes: 8
Views: 2197
Reputation: 11
I took a different approach, monkey patching the FlatpageForm Meta to use a custom widget for sites.
from django.forms import SelectMultiple
from django.conf import settings
from django.contrib.flatpages.forms import FlatpageForm
class PreSelectDefaultSiteOnCreateSelectMultiple(SelectMultiple):
def render(self, name, value, attrs=None, choices=()):
if value is None:
# None in the add form, a list, possibly empty, in
# the edit form. So we're adding a new instance here.
value = [settings.SITE_ID]
return super(PreSelectDefaultSiteOnCreateSelectMultiple, self
).render(name, value, attrs, choices)
def flatpages():
"""Hack the sites field widget.
"""
fpafm = FlatpageForm.Meta
if getattr(fpafm, 'widgets', None) is None:
fpafm.widgets = {}
fpafm.widgets['sites'] = PreSelectDefaultSiteOnCreateSelectMultiple
You must call flatpages() from somewhere before the admin might be used. I put the code above in a module admin.py in a package monkey_patches, then in my root urls.py, which gets imported the first time a request comes in, I put:
from monkey_patches.admin import flatpages
flatpages()
This is under Django 1.4 with python 2.7.3, but should work for older versions too.
Oh, and note that if you really want an empty sites association, you can deselect it intentionally, since this is just widget initialization. Subsequent edits will pass an empty list to render as value, which isn't None.
Bill, KE1G
Upvotes: 1
Reputation: 9193
allow for blank in sites field (models.py -> FlatPage.sites) and put this in your model Form (admin.py -> FlatPageForm)
def clean_sites(self):
sites = self.cleaned_data.get('sites')
print sites
return [Site.objects.get(id=settings.SITE_ID)]
edit:
I've come up with a better solution.
This makes current site already focused in ManyToMany sites field. Edit flatpages/admin.py. Add :from django.contrib.sites.models import Site
in the beggining of file and put following code into class FlatPageAdmin
:
def formfield_for_manytomany(self, db_field, request=None, **kwargs):
if db_field.name == "sites":
kwargs["initial"] = [Site.objects.get_current()]
return super(FlatPageAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
There is no need to allow for blank in sites field in FlatPage model
Upvotes: 9
Reputation: 412
Here is a completely working piece of code solving the original problem (to mark existing site default for all created flatpages):
from django.conf import settings
from django.contrib.flatpages.models import FlatPage
from django.contrib.sites.models import Site
class CustomFlatPage(FlatPage):
class Meta:
proxy = True
def save(self):
self.sites = [Site.objects.get(pk=settings.SITE_ID)]
super(CustomFlatPage, self).save()
Also this solution:
proxy = True
is not necessary to run syncbd in order to create an extra table for CustomFlatPage
model.Upvotes: 1
Reputation: 5837
Here is my code, it works:
class CustomFlatPage(FlatPage):
def save(self):
super(CustomFlatPage, self).save()
self.sites = [Site.objects.get(pk=1)]
super(CustomFlatPage, self).save()
Upvotes: 2