django ManyToManyField多对多关系的实例详解


Posted in Python onAugust 09, 2019

Django 的 ORM 有多种关系:一对一,多对一,多对多

各自定义的方式为 :

一对一: OneToOneField

多对一: ForeignKey

多对多: ManyToManyField

上边的描述太过数据而缺乏人性化,我们来更人性化一些:

多个属于一个,即 belong to : ForeignKey,多个属于一个

一个有一个,即 has one: OneToOneField

一个有很多个,即 has many: lots of A belong to B 与 B has many A,在建立 ForeignKey 时,另一个表会自动建立对应的关系

一个既有很多个,又属于很多个,即 has many and belong to : ManyToManyField,同样只能在一个model类中说明,关联表会自动建立。

多对多的关系:

举例:现有两张表,user表和group表。user表中的字段有用户名,邮箱,年龄等信息。而group表中有组名信息。我们知道一个用户可以属于多个组,一个组中也可以包含多个用户,所以这两张表的关系就是多对多的关系。

mysite/learn/models.py文件代码

#coding:utf8
from django.db import models

class Group(models.Model):
  Name = models.CharField(max_length=20)
  def __unicode__(self):
    return self.Name
    
    
class User(models.Model):
  Name = models.CharField(max_length=20)
  Email = models.CharField(max_length=50)
  group = models.ManyToManyField(Group,blank=True)
  def __unicode__(self):
    return self.Name
  def group_list(self):
    return ','.join([i.Name for i in self.group.all()])

创建两张表Group和User,Group表中只有组名“Name”这一个字段。而User表中有用户名“Name”,邮箱“Email”,组名“group”三个字段。

在User表中,由于group信息与Group表关联的,所以要在User表中设置

ManyToManyField
def group_list(self):
    return ','.join([i.Name for i in self.group.all()])

定义group_list函数,是为了在后台页面中显示group_list字段信息。group_list是后台页面显示的字段名称。

i.Name for i in self.group.all()

这里Name是Group表中的Name字段,self.group中的group是User表自己的group字段

mysite/admin.py文件中的代码

from django.contrib import admin
from learn.models import *
# Register your models here.

class UserAdmin(admin.ModelAdmin):
  list_display = ['id','Name','Email','group_list']
admin.site.register(User,UserAdmin)

class GroupAdmin(admin.ModelAdmin):
  list_display = ['id','Name']
admin.site.register(Group,GroupAdmin)

访问admin后台管理页面

在group表中创建组

django ManyToManyField多对多关系的实例详解

在user表中创建用户,Group字段选择用户组。

django ManyToManyField多对多关系的实例详解

django ManyToManyField多对多关系的实例详解

仔细看上面的截图,会发现一个问题-->在Group表中只有组名字段,但是看不到每个组中都有哪些用户。而User表中可以看到group_list字段,所以如果希望在Group中显示用户信息,可以仿照User表的做法,mysite/learn/models.py文件代码

#coding:utf8
from django.db import models

class Group(models.Model):
  Name = models.CharField(max_length=20)
  def user_list(self):
    return ','.join([i.Name for i in self.user_set.all()])
  def __unicode__(self):
    return self.Name
class User(models.Model):
  Name = models.CharField(max_length=20)
  Email = models.CharField(max_length=50)
  group = models.ManyToManyField(Group,blank=True)
  def __unicode__(self):
    return self.Name
  def group_list(self):
    return ','.join([i.Name for i in self.group.all()])

django ManyToManyField多对多关系的实例详解

在learn/admin.py文件中加上user_list字段

django ManyToManyField多对多关系的实例详解

再次访问admin后台管理页面,在group表中可以看到user_list信息了。

django ManyToManyField多对多关系的实例详解

正向查询和反向查询

正向查询:

上面我们创建了两张表user和group,现在我想查询user表中某个用户的所属组

进入django shell命令行

python manage.py shell
>>> from learn.models import *
>>> User.objects.all()
[<User: 老黄>, <User: 老张>, <User: 老王>]
>>> User.objects.all()[0]
<User: 老黄>
>>> User.objects.all()[0].Email
u'laohuang@qq.com'
>>> User.objects.all()[0].group.all()
[<Group: CEO>, <Group: COO>]
>>> User.objects.all()[0].group.all()[0].Name
u'CEO'
>>> User.objects.all()[0].group.all()[0].id

mysite/models.py文件中的每一个类都是一个对象,使用

User.objects.all()

可以获取所有对象,它是一个列表

[<User: 老黄>, <User: 老张>, <User: 老王>]

获取第一个对象

>>> User.objects.all()[0]
<User: 老黄>

获取老黄这个对象的邮箱属性的值

>>> User.objects.all()[0].Email
u'laohuang@qq.com'

获取用户所属组的组名,和id

>>> User.objects.all()[0].group.all()[0].Name
u'CEO'
>>> User.objects.all()[0].group.all()[0].id

反向查询:

>>> from learn.models import * ##导入models中所有的类

>>> Group.objects.all()  ##查看Group表中所有的对象
[<Group: CEO>, <Group: CTO>, <Group: COO>, <Group: VP>]

>>> Group.objects.all()[0] ##查看Group表中第一个对象CEO
<Group: CEO>

>>> Group.objects.all()[0].Name ##查看CEO这个对象的Name属性
u'CEO'

>>> Group.objects.all()[0].user_set.all() ##反向查看CEO这个对象的用户名
[<User: 老黄>]

>>> Group.objects.all()[0].user_set.all()[0]
<User: 老黄>

>>> Group.objects.all()[0].user_set.all()[0].Email ##反向查看CEO这个对象的Email
u'laohuang@qq.com'

>>> Group.objects.all()[0].user_set.all()[0].Name 
u'\u8001\u9ec4'

以上这篇django ManyToManyField多对多关系的实例详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之不要红头文件(1)
Sep 28 Python
python实现批量改文件名称的方法
May 25 Python
使用FastCGI部署Python的Django应用的教程
Jul 22 Python
Python实现各种排序算法的代码示例总结
Dec 11 Python
python实现多线程行情抓取工具的方法
Feb 28 Python
python3.4.3下逐行读入txt文本并去重的方法
Apr 29 Python
Python爬虫框架Scrapy基本用法入门教程
Jul 26 Python
Python设计模式之命令模式原理与用法实例分析
Jan 11 Python
python re库的正则表达式入门学习教程
Mar 08 Python
python3 写一个WAV音频文件播放器的代码
Sep 27 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
Feb 26 Python
python 实现在无序数组中找到中位数方法
Mar 03 Python
python虚拟环境的安装和配置(virtualenv,virtualenvwrapper)
Aug 09 #Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
Aug 09 #Python
对django2.0 关联表的必填on_delete参数的含义解析
Aug 09 #Python
python实现美团订单推送到测试环境,提供便利操作示例
Aug 09 #Python
正则给header的冒号两边参数添加单引号(Python请求用)
Aug 09 #Python
基于django ManyToMany 使用的注意事项详解
Aug 09 #Python
Django在admin后台集成TinyMCE富文本编辑器的例子
Aug 09 #Python
You might like
比较全的PHP 会话(session 时间设定)使用入门代码
2008/06/05 PHP
Codeigniter生成Excel文档的简单方法
2014/06/12 PHP
php以fastCGI的方式运行时文件系统权限问题及解决方法
2015/05/11 PHP
PHP获得数组交集与差集的方法
2015/06/10 PHP
学习php设计模式 php实现合成模式(composite)
2015/12/08 PHP
深入认识javascript中的eval函数
2009/11/02 Javascript
用js实现层随着内容大小动态渐变改变 推荐
2009/12/19 Javascript
JavaScript Array Flatten 与递归使用介绍
2011/10/30 Javascript
js获取网页可见区域、正文以及屏幕分辨率的高度
2014/05/15 Javascript
jQuery对象的length属性用法实例
2014/12/27 Javascript
对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解
2016/04/11 Javascript
jQuery自定义数值抽奖活动代码
2016/06/11 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
angularjs ocLazyLoad分步加载js文件实例
2017/01/17 Javascript
vue-router 中router-view不能渲染的解决方法
2017/05/23 Javascript
Vue2.0实现将页面中表格数据导出excel的实例
2017/08/09 Javascript
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
Angular 开发学习之Angular CLI的安装使用
2017/12/31 Javascript
ES6 Array常用扩展的应用实例分析
2019/06/26 Javascript
Node.JS用纯JavaScript生成图片或滑块式验证码功能
2019/09/12 Javascript
在js文件中引入(调用)另一个js文件的三种方法
2020/09/11 Javascript
[02:13] 完美世界DOTA2联赛PWL DAY5集锦
2020/11/03 DOTA
Python中文字符串截取问题
2015/06/15 Python
Python的GUI框架PySide的安装配置教程
2016/02/16 Python
python实现图片文件批量重命名
2020/03/23 Python
Python使用sort和class实现的多级排序功能示例
2018/08/15 Python
python实现京东订单推送到测试环境,提供便利操作示例
2019/08/09 Python
德国婴儿推车和儿童安全座椅商店:BABYSHOP
2016/09/01 全球购物
.NET面试题:什么是反射
2016/09/30 面试题
接口的多继承会带来哪些问题
2015/08/17 面试题
应届生人事助理求职信
2013/11/09 职场文书
建筑工程技术应届生求职信
2013/11/17 职场文书
物流司机岗位职责
2013/12/28 职场文书
2015年社区统计工作总结
2015/04/21 职场文书
格列夫游记读书笔记
2015/07/01 职场文书
MySQL 分区表中分区键为什么必须是主键的一部分
2022/03/17 MySQL