系统的了解DJANGO中数据MODULES的相关性引用
数据库结构如下:
from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def __str__(self): # __unicode__ on Python 2 return self.name class Author(models.Model): name = models.CharField(max_length=50) email = models.EmailField() def __str__(self): # __unicode__ on Python 2 return self.name class Entry(models.Model): blog = models.ForeignKey(Blog) headline = models.CharField(max_length=255) body_text = models.TextField() pub_date = models.DateField() mod_date = models.DateField() authors = models.ManyToManyField(Author) n_comments = models.IntegerField() n_pingbacks = models.IntegerField() rating = models.IntegerField() def __str__(self): # __unicode__ on Python 2 return self.headline
终于对这个东东有个系统性的了解了。
真正要用时,还是要查一查的。。
Related objects¶
When you define a relationship in a model (i.e., a ForeignKey, OneToOneField, or ManyToManyField), instances of that model will have a convenient API to access the related object(s).
Using the models at the top of this page, for example, an Entry object e can get its associated Blog object by accessing the blogattribute: e.blog.
(Behind the scenes, this functionality is implemented by Python descriptors. This shouldn’t really matter to you, but we point it out here for the curious.)
Django also creates API accessors for the “other” side of the relationship – the link from the related model to the model that defines the relationship. For example, a Blog object b has access to a list of all related Entry objects via the entry_set attribute:b.entry_set.all().
All examples in this section use the sample Blog, Author and Entry models defined at the top of this page.
One-to-many relationships¶
Forward¶
If a model has a ForeignKey, instances of that model will have access to the related (foreign) object via a simple attribute of the model.
Example:
>>> e = Entry.objects.get(id=2) >>> e.blog # Returns the related Blog object.
You can get and set via a foreign-key attribute. As you may expect, changes to the foreign key aren’t saved to the database until you callsave(). Example:
>>> e = Entry.objects.get(id=2) >>> e.blog = some_blog >>> e.save()
If a ForeignKey field has null=True set (i.e., it allows NULL values), you can assign None to remove the relation. Example:
>>> e = Entry.objects.get(id=2) >>> e.blog = None >>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
Forward access to one-to-many relationships is cached the first time the related object is accessed. Subsequent accesses to the foreign key on the same object instance are cached. Example:
>>> e = Entry.objects.get(id=2) >>> print(e.blog) # Hits the database to retrieve the associated Blog. >>> print(e.blog) # Doesn't hit the database; uses cached version.
Note that the select_related() QuerySet method recursively prepopulates the cache of all one-to-many relationships ahead of time. Example:
>>> e = Entry.objects.select_related().get(id=2) >>> print(e.blog) # Doesn't hit the database; uses cached version. >>> print(e.blog) # Doesn't hit the database; uses cached version.
Following relationships “backward”¶
If a model has a ForeignKey, instances of the foreign-key model will have access to a Manager that returns all instances of the first model. By default, this Manager is named FOO_set, where FOO is the source model name, lowercased. This Manager returns QuerySets, which can be filtered and manipulated as described in the “Retrieving objects” section above.
Example:
>>> b = Blog.objects.get(id=1) >>> b.entry_set.all() # Returns all Entry objects related to Blog. # b.entry_set is a Manager that returns QuerySets. >>> b.entry_set.filter(headline__contains='Lennon') >>> b.entry_set.count()
You can override the FOO_set name by setting the related_name parameter in the ForeignKey definition. For example, if the Entrymodel was altered to blog = ForeignKey(Blog, related_name='entries'), the above example code would look like this:
>>> b = Blog.objects.get(id=1) >>> b.entries.all() # Returns all Entry objects related to Blog. # b.entries is a Manager that returns QuerySets. >>> b.entries.filter(headline__contains='Lennon') >>> b.entries.count()
Using a custom reverse manager¶
By default the RelatedManager used for reverse relations is a subclass of the default manager for that model. If you would like to specify a different manager for a given query you can use the following syntax:
from django.db import models class Entry(models.Model): #... objects = models.Manager() # Default Manager entries = EntryManager() # Custom Manager b = Blog.objects.get(id=1) b.entry_set(manager='entries').all()
If EntryManager performed default filtering in its get_queryset() method, that filtering would apply to the all() call.
Of course, specifying a custom reverse manager also enables you to call its custom methods:
b.entry_set(manager='entries').is_published()
Additional methods to handle related objects¶
In addition to the QuerySet methods defined in “Retrieving objects” above, the ForeignKey Manager has additional methods used to handle the set of related objects. A synopsis of each is below, and complete details can be found in the related objects reference.
- add(obj1, obj2, ...)
- Adds the specified model objects to the related object set.
- create(**kwargs)
- Creates a new object, saves it and puts it in the related object set. Returns the newly created object.
- remove(obj1, obj2, ...)
- Removes the specified model objects from the related object set.
- clear()
- Removes all objects from the related object set.
To assign the members of a related set in one fell swoop, just assign to it from any iterable object. The iterable can contain object instances, or just a list of primary key values. For example:
b = Blog.objects.get(id=1) b.entry_set = [e1, e2]
In this example, e1 and e2 can be full Entry instances, or integer primary key values.
If the clear() method is available, any pre-existing objects will be removed from the entry_set before all objects in the iterable (in this case, a list) are added to the set. If the clear() method is not available, all objects in the iterable will be added without removing any existing elements.
Each “reverse” operation described in this section has an immediate effect on the database. Every addition, creation and deletion is immediately and automatically saved to the database.
Many-to-many relationships¶
Both ends of a many-to-many relationship get automatic API access to the other end. The API works just as a “backward” one-to-many relationship, above.
The only difference is in the attribute naming: The model that defines the ManyToManyField uses the attribute name of that field itself, whereas the “reverse” model uses the lowercased model name of the original model, plus '_set' (just like reverse one-to-many relationships).
An example makes this easier to understand:
e = Entry.objects.get(id=3) e.authors.all() # Returns all Author objects for this Entry. e.authors.count() e.authors.filter(name__contains='John') a = Author.objects.get(id=5) a.entry_set.all() # Returns all Entry objects for this Author.
Like ForeignKey, ManyToManyField can specify related_name. In the above example, if the ManyToManyField in Entry had specified related_name='entries', then each Author instance would have an entries attribute instead of entry_set.
One-to-one relationships¶
One-to-one relationships are very similar to many-to-one relationships. If you define a OneToOneField on your model, instances of that model will have access to the related object via a simple attribute of the model.
For example:
class EntryDetail(models.Model): entry = models.OneToOneField(Entry) details = models.TextField() ed = EntryDetail.objects.get(id=2) ed.entry # Returns the related Entry object.
The difference comes in “reverse” queries. The related model in a one-to-one relationship also has access to a Manager object, but thatManager represents a single object, rather than a collection of objects:
e = Entry.objects.get(id=2) e.entrydetail # returns the related EntryDetail object
If no object has been assigned to this relationship, Django will raise a DoesNotExist exception.
Instances can be assigned to the reverse relationship in the same way as you would assign the forward relationship:
e.entrydetail = ed
How are the backward relationships possible?¶
Other object-relational mappers require you to define relationships on both sides. The Django developers believe this is a violation of the DRY (Don’t Repeat Yourself) principle, so Django only requires you to define the relationship on one end.
But how is this possible, given that a model class doesn’t know which other model classes are related to it until those other model classes are loaded?
The answer lies in the app registry. When Django starts, it imports each application listed in INSTALLED_APPS, and then the modelsmodule inside each application. Whenever a new model class is created, Django adds backward-relationships to any related models. If the related models haven’t been imported yet, Django keeps tracks of the relationships and adds them when the related models eventually are imported.
For this reason, it’s particularly important that all the models you’re using be defined in applications listed in INSTALLED_APPS. Otherwise, backwards relations may not work properly.
系统的了解DJANGO中数据MODULES的相关性引用的更多相关文章
- Django中数据查询(万能下换线,聚合,F,Q)
数据查询中万能的下划线基本用法: __contains: 包含 __icontains: 包含(忽略大小写) __startswith: 以什么开头 __istartswith: 以什么开头(忽略大小 ...
- Django:(博客系统)使用使用mysql数据->后台管理tag/post/category的配置
Django后台一般是不需要人为的去开发的,因为django已经通过配置实现哪些模块是后台需要管理,如何排序,列表展示哪些列,列显示名称,是否为空(默认值),过滤条件,分页页数,列表中哪些项可编辑等等 ...
- Django模板系统(非常详细)(后台数据如何展示在前台)
前面的章节我们看到如何在视图中返回HTML,但是HTML是硬编码在Python代码中的这会导致几个问题:1,显然,任何页面的改动会牵扯到Python代码的改动网站的设计改动会比Python代码改动更频 ...
- Django中的权限系统
Django中已经为我们设置好了基本的权限系统,在定义好model同步数据库后,在每个库下面都会有一张 'auth_permission' 表.该表里面记录了每条权限的描述(name字段,can do ...
- Django中Ajax提交数据的CSRF问题
错误信息: Forbidden (CSRF token missing or incorrect.): 什么是CSRF: django为用户实现防止跨站请求伪造的功能,通过中间件 django.mid ...
- django中使用POST方法 获取POST数据
在django中获取post数据,首先要规定post发送的数据类型是什么. 1.获取POST中表单键值数据 如果要在django的POST方法中获取表单数据,则在客户端使用JavaScript发送PO ...
- Django model中数据批量导入bulk_create()
在Django中需要向数据库中插入多条数据(list).使用如下方法,每次save()的时候都会访问一次数据库.导致性能问题: for i in resultlist: p = Account(nam ...
- django中ModelForm save方法 以及快速生成空表单或包含数据的表单 包含错误信息
django中ModelForm学习系列一~save方法 Model代码 from django.db import models # Create your models here. class P ...
- django 中的路由系统(url)
路由系统 根据Django约定,一个WSGI应用里最核心的部件有两个:路由表和视图.Django框架 的核心功能就是路由:根据HTTP请求中的URL,查找路由表,将HTTP请求分发到 不同的视图去处理 ...
随机推荐
- Ganymed SSH-2 for Java
Ganymed SSH-2 for Java是一个纯Java实现的SHH2库,官网为http://www.ganymed.ethz.ch/ssh2/,最新的更新时间为2006年10月,在用之前,请仔细 ...
- Eclipse部署多个Web项目内存溢出,java.lang.OutOfMemoryError: PermGen space
Eclipse部署多个Web项目内存溢出,java.lang.OutOfMemoryError: PermGen space >>>>>>>>>& ...
- 如何理解 Redux?
作者:Wang Namelos 链接:https://www.zhihu.com/question/41312576/answer/90782136 来源:知乎 著作权归作者所有,转载请联系作者获得授 ...
- Java联网技术之一HTTP
学到Java的联网技术,这里首先来看看关于URl, 要从网上获得内容, 需要实现下面的4步, 1.创建一个表示资源的网络地址的URL对象, 2.创建一个HttpURLConnection 连接对象 3 ...
- iOS 多张图片保存到相册问题(add multiple images to photo album)
不知道朋友们有木有做过多图保存到系统的相册这个需求,我在用`UIImageWriteToSavedPhotosAlbum`保存图片时候,在代理回调方`didFinishSavingWithError` ...
- 动态加载js、css 代码
一.原生js: /** * 加载js和css文件 * @param jsonData.path 前缀路径 * @param jsonData.url 需要加载的js路径或css路径 * @param ...
- 02_Jquery_03_类选择器
[简述] 类选择器就是通过类名(css类名)来查询元素! $(".myClass")就可以把所有包含了class="myClass"的元素查询出来 [index ...
- 九度OJ 1372 最大子向量和(连续子数组的最大和)
题目地址:http://ac.jobdu.com/problem.php?pid=1372 题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后,他又发话了:在 ...
- IOS 学习笔记 2015-03-18
Objective--C 一 关键字 1 KVC 动态设值,动态取值,类似雨java中的反射,而且私有的照样可以设置与获取 2 二 函数 1 retain 给对象引用计数器 + 1 2 release ...
- foreach的一点理解
首先什么样的数据才能实现foreach 1 实现IEnumerable这个接口 2 有GetEnumerable()这个方法 然后为啥实现这个接口或者有这个方法就可以实现foreach遍历 首先我先用 ...