We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第二章 数据库结构
本章节覆盖以下话题:
当你新建新的app时,要做的第一件事就是创建表现数据库结构的模型。我们假设你之前已经创建了Django的app,要是没有话马上创建一个,而且你也阅读并了解Django的官方教程。本章,我会向你演示在项目中的一些使数据库结构在不同
在Python这样的面向对象语言中,mixin类可以看作是是一个实现特性的接口。当一个模型使用mixin来扩展,它就实现了接口,包括它的所有字段,属性,和方法。Django模型中的Mixin可以在你想要于不同的模型再三地重复使用通用功能。
要开始的话,你需要创建一些可重复使用的mixin。mixin的某些典型例子会在后面章节展示。一个保存模型mixin的好地方就是utils模块。
utils
如果你要创建一个与他人共享的重复使用app,那就要把模型mixin放在app里,比如放在应用的base.py文件中。
base.py
在任何想要使用的mixin的Django应用中,创建models.py文件,并输入下面的代码:
models.py
#demo_app/models.py # -*- coding: UTF-8 -*- from django.db import models from django.utils.translation import ugettext_lazy as _ from utils.models import UrlMixin from utils.models import CreationModificationMixin from utils.models import MetaTagsMixin class Idea(UrlMixin, CreationModificationMixin, MetaTagsMixin): title = models.CharField(_("Title"), max_length=200) content = models.TextField(_("Content")) class Meta: verbose_name = _("Idea") verbose_name_plural = _("Ideas") def __unicode__(self): return self.title
Django的模型继承支持三种类型的继承:抽象基本类,多重继承,以及代理模型。模型mixin是拥有特殊字段,属性,和方法的模型类。当你创建Idea这样的模型,如前面的例子所示,它从UrlMixin ,CreationModificationMixin和MetaTagsMixin继承多有的特性。所有的抽象类字段都保存在所扩展模型字段的同一个数据表中。
Idea
UrlMixin
CreationModificationMixin
MetaTagsMixin
为了学习更多不同类型的模型继承,参考Django官方文档https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance。
每个模型都有一个自己的页面,较好的做法是定义get_absolute_url()方法。这个方法可以用在模板中,它也可以用在Django admin站点中以预览所保存的项目。然而,get_absolute_url是一种模棱两可的方法,因为它实际上返回的是URL路径而不是完整的URL。在这个技巧中,我会向你演示如何创建模型mixin,默认模型允许定义URL路径或者完整的URL,生成另外的路径,然后处理get_absolute_url方法的设置。
get_absolute_url()
get_absolute_url
如果你还没有完成创保存mixin的utils包。然后,在utils包内(可选的是,如果创建了一个重复使用的应用,那么你需要把base.py放在应用中)创建models.py文件。
按步骤地执行以下命令:
#utils/models.py # -*- coding: UTF-8 -*- import urlparse from django.db import models from django.contrib.sites.models import Site from django.conf import settings class UrlMixin(models.Model): """ A replacement for get_absolute_url() Models extending this mixin should have either get_url or get_url_path implemented. """ class Meta: abstract = True def get_url(self): if hasattr(self.get_url_path, "dont_recurse"): raise NotImplementedError try: path = self.get_url_path() except NotImplementedError: raise website_url = getattr(settings, "DEFAULT_WEBSITE_URL", "http://127.0.0.1:8000") return website_url + path get_url.dont_recurse = True def get_url_path(self): if hasattr(self.get_url, "dont_recurse"): raise NotImplementedError try: url = self.get_url() except NotImplementedError: raise bits = urlparse.urlparse(url) return urlparse.urlunparse(("", "") + bits[2:]) get_url_path.dont_recurse = True def get_absolute_url(self): return self.get_url_path()
# demo_app/models.py # -*- coding: UTF-8 -*- from django.db import models from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse from utils.models import UrlMixin class Idea(UrlMixin): title = models.CharField(_("Title"), max_length=200) #... get_url_path(self): return reverse("idea_details", kwargs={ "idea_id": str(self.pk) })
DEFAULT_WEBSITE_URL
#settings.py # ... DEFAULT_WEBSITE_URL = "http://www.example.com"
UrlMixin是一个拥有三种方法的抽象模型:get_url(), get_url_path(),get_absolute_url。get_url()或者get_url_path()方法预计会在所扩展的模型类中被重写,比如,Idea类。你可定义get_url,它是一个到对象的完整URL,get_url_path会把它剥离到路径。你也可以定义get_url_path,它是到对象的绝对路径,然后get_url会添加网站的URL到路径的开始。get_absolute_url方法会模仿get_url_path`。
get_url()
,
。
或者
方法预计会在所扩展的模型类中被重写,比如,
类。你可定义
,它是一个到对象的完整URL,
会把它剥离到路径。你也可以定义
,它是到对象的绝对路径,然后
会添加网站的URL到路径的开始。
方法会模仿
提示 通常的经验总是重写get_url_path方法。 当你在同一个网站中需要到一个对象的链接,可以在模板中,使用<a href="{{ idea.get_url_path }}">{{ idea.title }}</a>。对于电子邮件,RSS订阅或者API可以使用,<a href="{{ idea.get_url }}>"{{ idea.title }}</a>。
通常的经验总是重写get_url_path方法。
get_url_path
当你在同一个网站中需要到一个对象的链接,可以在模板中,使用<a href="{{ idea.get_url_path }}">{{ idea.title }}</a>。对于电子邮件,RSS订阅或者API可以使用,<a href="{{ idea.get_url }}>"{{ idea.title }}</a>。
<a href="{{ idea.get_url_path }}">{{ idea.title }}</a>
<a href="{{ idea.get_url }}>"{{ idea.title }}</a>
技巧:使用模型mixin 技巧:创建处理数据生成和修改的模型mixin 技巧:创建模型mixin以处理元标签 技巧:创建模型mixin处理通用关系
在模型中对于模型实例的创建和修改来说,一种常见的行为就是拥有时间戳。这个技巧中,我会向你演示如何给创建保存、修改模型的日期和时间。使用这样的mixin可以保证,所有的模型对于时间戳都使用相同的字段,以及拥有同样的行为。
打开utils包中的models.py文件,并输入以下的代码:
#utils/models.py # -*- coding: UTF-8 -*- from django.db import models from django.utils.translation import ugettext_lazy as _ from django.utils.timezone import now as timezone_now class CreationModificationDateMixin(models.Model): """ 可以创建和修改日期和时间的抽象基类。 """ created = models.DateTimeField( _("creation date and time"), editable=False, ) modified = models.DateTimeField( _("modification date and time"), null=True, editable=False, ) def save(self, *args, **kwargs): if not self.pk: self.created = timezone_now() else: #为了保证我们一直拥有创建数据,添加下面的条件语句 if not self.created: self.created = timezone_now() self.modified = timezone_now() super(CreationModificationDateMixin, self).save(*args, **kwargs) save.alters_data = True class Meta: abstract = True
CreationModificationDateMixin类是一个抽象模型,这意味着它所扩展的模型类会在同一个数据表中创建所有字段,即,这里没有一对一关系让表的处理变得过于负责。该mixin拥有两个日期-时间字段,以及一个在保存扩展模型会调用的save()方法。save()方法检查模型是否拥有主键,它针对于新建但还未保存的实例的这样情况。否则,如果主键存在,修改的日期就会被设置为当前的日期和时间。
CreationModificationDateMixin
save()
作为选择,你可以不使用save()方法,而使用auto_now_add和auto_now属性来created和修改字段以自动地创建和修改时间戳。
auto_now_add
auto_now
created
修改
参阅 使用模型mixin 创建模型mixin以处理meta标签 创建模型mixin以处理通用关系
使用模型mixin 创建模型mixin以处理meta标签 创建模型mixin以处理通用关系
如果你想要优化网站的搜索引擎,你不仅需要个每个页面都设置语义装饰,而且也需要合适的元标签。为了最大的灵活性,你需要有一种对在网站中有自己页面的所有对象都定义指定的元标签的方法。于此技法中,我们会向你演示如何模型mixin的字段,以及关联到元标签的方法。
和前面的技法一样,确保你为mixin准备了utils包。用你最喜欢的编辑器打开models.py文件。
于models.py文件中写入以下内容:
#utils/models.py # -*- coding: UTF-8 -*- from django.db import models from django.utils.translation import ugettext_lazy as _ from django.template.defaultfilters import escape from django.utils.safestring import mark_safe class MetaTagsMixin(models.Model): """ 用于<head>元素中由抽象基类所构成的元标签 """ meta_keywords = models.CharField( _("Keywords"), max_length=255, blank=True, help_text=_("Separate keywords by comma."), ) meta_description = models.CharField( _("Description"), max_length=255, blank=True, ) meta_author = models.CharField( _("Author"), max_length=255, blank=True, ) meta_copyright = models.CharField( _("Copyright"), max_length=255, blank=True, ) class Meta: abstract = True def get_meta_keyword(self): tag = u" " if self.meta_keywords: tag = u'<meta name="keywords" content="{}".format(escape(self.meta_author)) /> return mark_safe(tag) def get_meta_description(self): tag = u" " if self.meta_description: tag = u'<meta name="description" content="{1}".format(escape(self.meta_author)) /> return mark_safe(tag) def get_meta_author(self): tag = u" " if self.get_meta_author: tag = u'<meta name="author" content="{1}".format(escape(self.meta_author)) />' def get_meta_copyright(self): tag = u" " if self.meta_copyright: tag = u'<meta name="copyright" content="{}".format(escape(self.meta_copyright)) />' return mark_safe(tag) def get_meta_tags(self): return mark_safe(u" ".join( self.get_meta_keyword(), self.get_meta_description(), self.get_meta_author(), self.get_meta_copyright(), ))
该mixin添加了四个字段到模型扩展:
略
除了外键关系或者对对关系这样的常见数据库关系之外,Django还提供了一种关联一个模型到任意模型的实例。此概念称为通用关系。每个通用关系都有一个关联模型的内容类型,而且这个内容类型也保存为该模型实例的ID。
于此技法,我们会向你演示如何将通用关系的创建归纳为模型mixin。
在文本编辑器中打开utils包中的models.py文件,并输入以下的内容:
“ #utils/models.py # -*- coding: UTF-8 -*- from django.db import models from django.utils.translation import ugettext_lazy as _ from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic from django.core.exceptions import FieldError def object_relation_mixin_factory( prefix=None, prefix_verbose=None, add_related_name=False, limit_content_type_choices_to={}, limit_object_choices_to={}, is_required=False, )
The text was updated successfully, but these errors were encountered:
No branches or pull requests
第二章 数据库结构
本章节覆盖以下话题:
简介
当你新建新的app时,要做的第一件事就是创建表现数据库结构的模型。我们假设你之前已经创建了Django的app,要是没有话马上创建一个,而且你也阅读并了解Django的官方教程。本章,我会向你演示在项目中的一些使数据库结构在不同
使用模型mixin
在Python这样的面向对象语言中,mixin类可以看作是是一个实现特性的接口。当一个模型使用mixin来扩展,它就实现了接口,包括它的所有字段,属性,和方法。Django模型中的Mixin可以在你想要于不同的模型再三地重复使用通用功能。
准备开始
要开始的话,你需要创建一些可重复使用的mixin。mixin的某些典型例子会在后面章节展示。一个保存模型mixin的好地方就是
utils
模块。提示
如何做
在任何想要使用的mixin的Django应用中,创建
models.py
文件,并输入下面的代码:工作原理
Django的模型继承支持三种类型的继承:抽象基本类,多重继承,以及代理模型。模型mixin是拥有特殊字段,属性,和方法的模型类。当你创建
Idea
这样的模型,如前面的例子所示,它从UrlMixin
,
CreationModificationMixin
和MetaTagsMixin
继承多有的特性。所有的抽象类字段都保存在所扩展模型字段的同一个数据表中。还有更多
为了学习更多不同类型的模型继承,参考Django官方文档https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance。
参阅
使用相对URL方法创建一个模型mixin
每个模型都有一个自己的页面,较好的做法是定义
get_absolute_url()
方法。这个方法可以用在模板中,它也可以用在Django admin站点中以预览所保存的项目。然而,get_absolute_url
是一种模棱两可的方法,因为它实际上返回的是URL路径而不是完整的URL。在这个技巧中,我会向你演示如何创建模型mixin,默认模型允许定义URL路径或者完整的URL,生成另外的路径,然后处理get_absolute_url
方法的设置。准备开始
如果你还没有完成创保存mixin的
utils
包。然后,在utils
包内(可选的是,如果创建了一个重复使用的应用,那么你需要把base.py
放在应用中)创建models.py
文件。如何做
按步骤地执行以下命令:
utils
包的models.py
文件中添加以下内容:utils
包导入,然后在模型类中继承mixin,并定义get_absolute_url()
方法如下:DEFAULT_WEBSITE_URL
中设置如下内容:工作原理
UrlMixin
是一个拥有三种方法的抽象模型:get_url()
, get_url_path(),
get_absolute_url。
get_url()或者
get_url_path()方法预计会在所扩展的模型类中被重写,比如,
Idea类。你可定义
get_url,它是一个到对象的完整URL,
get_url_path会把它剥离到路径。你也可以定义
get_url_path,它是到对象的绝对路径,然后
get_url会添加网站的URL到路径的开始。
get_absolute_url方法会模仿
get_url_path`。参阅
创建处理数据生成和修改的模型mixin
在模型中对于模型实例的创建和修改来说,一种常见的行为就是拥有时间戳。这个技巧中,我会向你演示如何给创建保存、修改模型的日期和时间。使用这样的mixin可以保证,所有的模型对于时间戳都使用相同的字段,以及拥有同样的行为。
准备开始
如果你还没有完成创保存mixin的
utils
包。然后,在utils
包内(可选的是,如果创建了一个重复使用的应用,那么你需要把base.py
放在应用中)创建models.py
文件。如何做
打开
utils
包中的models.py
文件,并输入以下的代码:工作原理
CreationModificationDateMixin
类是一个抽象模型,这意味着它所扩展的模型类会在同一个数据表中创建所有字段,即,这里没有一对一关系让表的处理变得过于负责。该mixin拥有两个日期-时间字段,以及一个在保存扩展模型会调用的save()
方法。save()
方法检查模型是否拥有主键,它针对于新建但还未保存的实例的这样情况。否则,如果主键存在,修改的日期就会被设置为当前的日期和时间。作为选择,你可以不使用
save()
方法,而使用auto_now_add
和auto_now
属性来created
和修改
字段以自动地创建和修改时间戳。创建模型mixin以处理meta标签
如果你想要优化网站的搜索引擎,你不仅需要个每个页面都设置语义装饰,而且也需要合适的元标签。为了最大的灵活性,你需要有一种对在网站中有自己页面的所有对象都定义指定的元标签的方法。于此技法中,我们会向你演示如何模型mixin的字段,以及关联到元标签的方法。
准备开始
和前面的技法一样,确保你为mixin准备了
utils
包。用你最喜欢的编辑器打开models.py
文件。如何做
于
models.py
文件中写入以下内容:工作原理
该mixin添加了四个字段到模型扩展:
参阅
略
创建模型mixin以处理通用关系
除了外键关系或者对对关系这样的常见数据库关系之外,Django还提供了一种关联一个模型到任意模型的实例。此概念称为通用关系。每个通用关系都有一个关联模型的内容类型,而且这个内容类型也保存为该模型实例的ID。
于此技法,我们会向你演示如何将通用关系的创建归纳为模型mixin。
准备开始
工作原理
在文本编辑器中打开
utils
包中的models.py
文件,并输入以下的内容:The text was updated successfully, but these errors were encountered: