【发布时间】:2011-01-24 20:26:23
【问题描述】:
我主要为一个站点使用平面页面(来自站点框架)。如何为所有创建的平面页面标记现有站点默认值? 每次为创建的每个页面选择相同的站点都是浪费时间。有没有办法在模型或保存方法中覆盖它?
【问题讨论】:
-
您的意思是在 Django 管理员中?还是在一般模型上?
我主要为一个站点使用平面页面(来自站点框架)。如何为所有创建的平面页面标记现有站点默认值? 每次为创建的每个页面选择相同的站点都是浪费时间。有没有办法在模型或保存方法中覆盖它?
【问题讨论】:
允许在站点字段中留空 (models.py -> FlatPage.sites) 并将其放入您的模型表单 (admin.py -> FlatPageForm)
def clean_sites(self):
sites = self.cleaned_data.get('sites')
print sites
return [Site.objects.get(id=settings.SITE_ID)]
编辑:
我想出了一个更好的解决方案。
这使得当前站点已经专注于多对多站点领域。编辑 flatpages/admin.py。在文件开头添加:from django.contrib.sites.models import Site,并将以下代码放入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)
FlatPage 模型中的站点字段中不需要允许空白
【讨论】:
这是我的代码,它可以工作:
class CustomFlatPage(FlatPage):
def save(self):
super(CustomFlatPage, self).save()
self.sites = [Site.objects.get(pk=1)]
super(CustomFlatPage, self).save()
【讨论】:
这是解决原始问题的完整代码(标记所有创建的平面页面的现有站点默认值):
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()
还有这个解决方案:
proxy = True 不需要运行syncbd 来为CustomFlatPage 模型创建额外的表。【讨论】:
super(CustomFlatPage, self).save()需要加在self.sites = [Site.objects.get(pk=settings.SITE_ID)]之前
Site.objects.get(pk=settings.SITE_ID) 将返回您需要的一个站点,无论您创建了多少个站点,不是吗?
self.sites = Site.objects.all() 如果您想在某些特定站点中拥有它,那么只需使用 filter 而不是 @ 987654329@
我采取了不同的方法,猴子修补 FlatpageForm Meta 以使用网站的自定义小部件。
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
在使用管理员之前,您必须从某个地方调用 flatpages()。我将上面的代码放在monkey_patches包中的模块admin.py中,然后在我的根urls.py中,它在第一次请求进入时被导入,我输入:
from monkey_patches.admin import flatpages
flatpages()
这是在 Django 1.4 和 python 2.7.3 下,但也应该适用于旧版本。
哦,请注意,如果您真的想要一个空的站点关联,您可以有意取消选择它,因为这只是小部件初始化。随后的编辑将传递一个空列表以呈现为值,而不是 None。
比尔,KE1G
【讨论】: