正如在情景一中所解释的,要在多个站点间重用数据,仅需在模型中为Site添加一个多对多字段即可,例如:
from django.db import models from django.contrib.sites.models import Site class Article(models.Model): headline = models.CharField(maxlength=200) # ... sites = models.ManyToManyField(Site)
这是在数据库中为多个站点进行文章关联操作的基础步骤。在适当的位置使用该技术,你可以在多个站点中重复使用同一段 Django视图代码。继续Article模型范例,下面是一个可能的article_detail视图:
from django.conf import settings def article_detail(request, article_id): try: a = Article.objects.get(id=article_id, sites__id=settings.SITE_ID) except Article.DoesNotExist: raise Http404
举例来说,如果某篇文章仅仅能够出现在一个站点上,你可以使用下面这样的模型:
from django.db import models from django.contrib.sites.models import Site class Article(models.Model): headline = models.CharField(maxlength=200) # ... site = models.ForeignKey(Site)
在底层,通过在 Django视图中使用多站点框架,你可以让视图根据调用站点不同而完成不同的工作,例如:
from django.conf import settings def my_view(request): if settings.SITE_ID == 3: # Do something. else: # Do something else.
当然,像那样对站点 ID进行硬编码是比较难看的。略为简洁的完成方式是查看当前的站点域:
from django.conf import settings from django.contrib.sites.models import Site def my_view(request): current_site = Site.objects.get(id=settings.SITE_ID) if current_site.domain == 'foo测试数据': # Do something else: # Do something else.
from django.contrib.sites.models import Site def my_view(request): current_site = Site.objects.get_current() if current_site.domain == 'foo测试数据': # Do something else: # Do something else.
正如情景二中所解释的那样,对于储存站名和域名的 DRY (Dont Repeat Yourself)方法(在一个位置储存站名和域名)来说,只需引用当前Site对象的name和domain。例如:
from django.contrib.sites.models import Site from django.core.mail import send_mail def register_for_newsletter(request): # Check form values, etc., and subscribe the user. # ... current_site = Site.objects.get_current() send_mail('Thanks for subscribing to %s alerts' % current_site.name, 'Thanks for your subscription. We appreciate it./n/n-The %s team.' % current_site.name, 'editor@%s' % current_site.domain, [user_email]) # ...
完成这项工作的一种更加灵活(但重量级也更大)的方法是使用 Django的模板系统。假定 Lawrence测试数据和
LJWorld测试数据 各自拥有不同的模板目录(TEMPLATE_DIRS),你可将工作轻松地转交给模板系统,如下所示:
from django.core.mail import send_mail from django.template import loader, Context def register_for_newsletter(request): # Check form values, etc., and subscribe the user. # ... subject = loader.get_template('alerts/subject.txt').render(Context({})) message = loader.get_template('alerts/message.txt').render(Context({})) send_mail(subject, message, 'do-not-reply@example测试数据', [user_email]) # ...
Django 的get_absolute_url()约定对与获取不带域名的对象 URL非常理想,但在某些情形下,你可能想显示某个对象带有http://和域名以及所有部分的完整
URL。要完成此工作,你可以使用多站点框架。下面是个简单的例子:
>>> from django.contrib.sites.models import Site >>> obj = MyModel.objects.get(id=3) >>> obj.get_absolute_url() '/mymodel/objects/3/' >>> Site.objects.get_current().domain 'example测试数据' >>> 'http://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url())
from django.db import models from django.contrib.sites.models import Site from django.contrib.sites.managers import CurrentSiteManager class Photo(models.Model): photo = models.FileField(upload_to='/home/photos') photographer_name = models.CharField(maxlength=100) pub_date = models.DateField() site = models.ForeignKey(Site) objects = models.Manager() on_site = CurrentSiteManager()
换言之,以下两条语句是等效的:
Photo.objects.filter(site=settings.SITE_ID)
Photo.on_site.all()
CurrentSiteManager是如何知道Photo的哪个字段是Site呢?缺省情况下,它会查找一个叫做site的字段。如果模型中有个外键或多对多字段叫做site之外的名字,你必须显示地将它作为参数传递给CurrentSiteManager。下面的模型中有个叫做publish_on的字段,如下所示:
from django.db import models from django.contrib.sites.models import Site from django.contrib.sites.managers import CurrentSiteManager class Photo(models.Model): photo = models.FileField(upload_to='/home/photos') photographer_name = models.CharField(maxlength=100) pub_date = models.DateField() publish_on = models.ForeignKey(Site) objects = models.Manager() on_site = CurrentSiteManager('publish_on')
该应用所带来的FlatPage模型在django/contrib/flatpages/models.py进行定义,如下所示:
from django.db import models from django.contrib.sites.models import Site class FlatPage(models.Model): url = models.CharField(maxlength=100) title = models.CharField(maxlength=200) content = models.TextField() enable_comments = models.BooleanField() template_name = models.CharField(maxlength=70, blank=True) registration_required = models.BooleanField() sites = models.ManyToManyField(Site)
前面已经提到,简单页面表现为django/contrib/flatpages/models.py中的标准 Django模型。因此,你可以通过
Django数据库 API
来存取简单页面对象,例如:
>>> from django.contrib.flatpages.models import FlatPage >>> from django.contrib.sites.models import Site >>> fp = FlatPage( ... url='/about/', ... title='About', ... content='<p>About this site...</p>', ... enable_comments=False, ... template_name='', ... registration_required=False, ... ) >>> fp.save() >>> fp.sites.add(Site.objects.get(id=1)) >>> FlatPage.objects.get(url='/about/') <FlatPage: /about/ -- About>
以下是一个flatpages/default.html模板范例:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://HdhCmsTestw3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>{{ flatpage.title }}</title> </head> <body> {{ flatpage.content }} </body> </html>
django/contrib/redirects/models.py中的一个标准 Django模型代表了重定向。因此,你可以通过 Django数据库
API 来存取重定向对象,例如:
>>> from django.contrib.redirects.models import Redirect >>> from django.contrib.sites.models import Site >>> red = Redirect( ... site=Site.objects.get(id=1), ... old_path='/music/', ... new_path='/sections/arts/music/', ... ) >>> red.save() >>> Redirect.objects.get(old_path='/music/') <Redirect: /music/ ---> /sections/arts/music/>
{{ object.content|textile }}
要激活这些过滤器,仅需将'django.contrib.markup'添加到INSTALLED_APPS设置中。一旦完成了该项工作,在模板中使用{%
load markup %}就能使用这些过滤器。要想掌握更多信息的话,可阅读django/contrib/markup/templatetags/markup.py.内的源代码。
以上就是Django集成的子框架的内容,更多相关内容请关注PHP中文网(HdhCmsTestgxlcms测试数据)!