Django ORM 外键操作

经常修改的东西一般不放到内存里面,而是放到一张表里。表跟表之间是可以存在关系的,最基本的就是一对多的关系。

models.ForeignKey(ColorDic)

1. 在models.py中创建2张表,UserGroup中有2列数据,UserInfo中有3列数据。

from django.db import models
# Create your models here.
class UserGroup(models.Model):
uid=models.AutoField(primary_key=True)
caption=models.CharField(max_length=32,unique=True) class UserInfo(models.Model):
username=models.CharField(max_length=32,blank=True,verbose_name='用户名')
password = models.CharField(max_length=64,help_text='pwd')

需要运行python manage.py makemigrations/python manage.py migrate 这两句才能生效。

2. 在表中创建数据备用

创建好的数据如下:

3. 创建外键关联 user_group=models.ForeignKey('UserGroup',to_field='uid',default=1)

外键关联,因为是外键关联,所以它里面存的数据是上表中的uid值。

to_field='uid',代表要跟那张表里面的uid进行关联。这个字段不加也可以,那么默认用的就是主键。

一定一定要记住,这里有1个特殊的现象,虽然我们创建的列名是user_group字段 (外键关联了UserGroup中的uid字段)。但是django会自动给我们增加了1个id字段。 在数据库中的实际列名为user_group_id 。

user_group代指的是UserGroup对象,对象里面封装了好多值(uid,caption)。

我们想的是这样的:

实际上在数据库中是这样的:

4. 怎么样通过外键去获取到用户属于哪个组呢?这块很重要 

for row in user_list:
  #print(row.user_group_id) #代表数据库中真实存在的那个数据   
  #print(row.user_group) #user_group是通过外键关联生成的,代指的是UserGroup类及里面的所有对象,里面封装了(uid,caption)
  #print(row.user_group.uid)  #获取UserGroup中的uid值

  #print(row.user_group.caption)  #获取UserGroup中的caption值

比如我们想要在user_info页面显示用户名以及用户属于哪个组

在user_info函数里面做个测试,看应该怎么取值。

def user_info(request):     
  if request.method=='GET':
    user_list=models.UserInfo.objects.all()
#print(user_list.query)
# QuerySet[obj(id,username,password,user_group_id,user_group(uid,caption)]
# user_info里面封装了(id,username,password,user_group_id,user_group)这5个字段,其中user_group代表的是UserGroup类,
它里面还封装了(uid,caption)这2个字段。
#for row in user_list:
# print(row.id)
# print(row.user_group.caption)

打印一下user_group,证明确实是个对象

5. 修改user_info.html模板,得到想要的效果。 

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="height:48px;background-color:black;color:white">
欢迎登陆教育系统
</div>
<div>
<div style="position:absolute;top:48px;bottom:0;left:0;width:200px;background-color:brown;">
<a class="menu" href="/user_info/">用户管理</a>
<a class="menu" href="/user_group/">用户组管理</a>
</div> <div style="position:absolute;top:48px;left:210px;bottom:0;right:0;overflow:auto"> <h1>添加用户</h1>
<form method="POST" action="/user_info/">
<input type="text" name="user"/>
<input type="text" name="pwd"/>
<input type="submit" value="添加"/>
</form> <h1>用户列表</h1>
<ul>
{% for row in user_list%}
<li>
<a href="/userdetail-{{row.id}}">{{row.username}}</a> |
<span>{{row.user_group.caption}}</span>
<a href="/userdel-{{row.id}}/">删除</a> |
<a href="/useredit-{{row.id}}/">编辑</a>
</li>
{% endfor %}
</ul> </div>
</div>
</body>
</html>

效果:

至此就实现了通过跨表去获取数据了。

6. 接下来看怎么样在有外键的情况下去新建一条数据。

新建数据还是在orm中实现

在表中查看,已经新增了1条记录。

其实创建数据的时候,有以下2种方式,上面采用的是推荐的第二种方式。第一种方式需要再查一次表,不推荐使用。

7. 在页面上增加用户的时候,提供一个下拉框,可以选择用户处于哪个组。

8. 如果像这样,在user_info页面把用户组的可选项都写死的话,如果数据库中又增加了一个选项的话,那么这个选项是没法出现在user_info页面的,所以我们应该把group_list的可选项写成是动态的。

在view.py中的user_info中增加程序获取group_list的信息

在user_info.html中动态循环获得数据

效果图

测试,在数据库中手动增加1条记录

在浏览器中已经有这个可选项了。这样就实现了动态的同步。

与本节内容有关的程序粘贴一部分:

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^orm/', views.orm),
url(r'^index/', views.index),
url(r'^user_info/', views.user_info),
url(r'^user_group/', views.user_group),
url(r'^userdetail-(?P<nid>\d+)/', views.user_detail),
url(r'^userdel-(?P<nid>\d+)/', views.user_del),
url(r'^useredit-(?P<nid>\d+)/', views.user_edit),
url(r'^detail-(?P<nid>\d+).html', views.detail), ]

views.py

from django.shortcuts import render,HttpResponse,redirect
import os from app01 import models
def orm(request):
#更新
#models.UserInfo.objects.filter(id=2).update(user_group=2) #新建
#models.UserInfo.objects.create(id=3).update(user_group=2)
#models.UserInfo.objects.create(username='root',password=123)
#models.UserInfo.objects.create(username='Jack', password=433)
#models.UserInfo.objects.create(username='Alex', password=999)
#models.UserGroup.objects.create(caption='VIP')
#models.UserGroup.objects.create(caption='Normal') #删除
#models.UserGroup.objects.filter(id=2).delete() #查询
result=models.UserInfo.objects.all()
#print(result) for row in result:
print(row.id,row.username,row.password)
print(result) #在有外键的情况下,新建一条数据。
models.UserInfo.objects.create(
username='root1',
password='123',
user_group_id=2,
)
return HttpResponse('orm') USER_LIST={
'1':{'name':'root1','email':'root1@126.com'},
'2':{'name':'root2','email':'root2@126.com'},
'3':{'name':'root3','email':'root3@126.com'},
} def index(request):
models.UserInfo.objects.create(caption='DBA')
return render(request,'index.html') def user_info(request):
if request.method=='GET':
user_list=models.UserInfo.objects.all()
group_list=models.UserGroup.objects.all()
#print(group_list)
#print(user_list.query)
# QuerySet[obj(id,username,password,user_group_id,user_group(uid,caption)]
#for row in user_list:
#print(row.id)
#print(row.user_group)
#print(row.user_group.uid)
#print(row.user_group.caption)
return render(request,'user_info.html',{'user_list':user_list,'group_list':group_list}) elif request.method=='POST':
u=request.POST.get('user')
p=request.POST.get('pwd')
print(u,p)
models.UserInfo.objects.create(username=u,password=p)
return redirect('/user_info/') def user_group(request):
return render(request,'user_group.html') def user_detail(request,nid):
obj=models.UserInfo.objects.filter(id=nid).first()
return render(request,'user_detail.html',{'obj':obj}) def user_del(request,nid):
models.UserInfo.objects.filter(id=nid).delete()
return redirect('/user_info/') def user_edit(request,nid):
if request.method=='GET':
obj=models.UserInfo.objects.filter(id=nid).first()
return render(request,'user_edit.html',{'obj':obj})
elif request.method=='POST':
nid=request.POST.get('id')
u=request.POST.get('username')
p = request.POST.get('password')
models.UserInfo.objects.filter(id=nid).update(username=u,password=p)
return redirect('/user_info/') def detail(request,nid):
detail_info=USER_LIST[nid]
return render(request,'detail.html',{'detail_info':detail_info}) #Create your views here. def login(request):
print(request.method)
if request.method=='GET':
return render(request, 'login.html')
elif request.method=='POST':
u=request.POST.get('user')
p=request.POST.get('pwd')
obj=models.UserInfo.objects.filter(username=u,password=p).first()
if obj:
return redirect('/index/')
else:
return render(request,'login.html')
else:
return redirect('/index/')

models.py

from django.db import models
# Create your models here.
class UserGroup(models.Model):
uid=models.AutoField(primary_key=True) #表示uid是自增列,它必须同时还是主键。表里面只能有1个自增列,所以总共只有2列了。uid+caption列
caption=models.CharField(max_length=32,unique=True)
#运行后,django会生成一张名字为app01_userinfo的表。
class UserInfo(models.Model):
username=models.CharField(max_length=32)
password = models.CharField(max_length=32)
user_group=models.ForeignKey('UserGroup',to_field='uid',default=1)
#外键关联,因为是外键关联,所以它里面存的数据是上表中的uid值。
#to_field='uid',代表要跟那张表里面的uid进行关联。这个字段不加也可以,那么默认用的就是主键。
# 虽然我们创建的列名是user_group字段,但是django会自动给我们增加1个id字段。 在数据库中的实际列名为user_group_id
# user_group代指的是UserGroup对象,对象里面封装了好多值(uid,caption)。 user_list=UserInfo.objects.all()
for row in user_list:
print(row.user_group_id) #代表数据库中真实存在的那个数据
#print(row.user_group) #user_group是通过外键关联生成的,代指的是UserGroup类及里面的所有对象,里面封装了(uid,caption)
#print(row.user_group.caption)

user_info.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="height:48px;background-color:black;color:white">
欢迎登陆教育系统
</div>
<div>
<div style="position:absolute;top:48px;bottom:0;left:0;width:200px;background-color:brown;">
<a class="menu" href="/user_info/">用户管理</a>
<a class="menu" href="/user_group/">用户组管理</a>
</div> <div style="position:absolute;top:48px;left:210px;bottom:0;right:0;overflow:auto"> <h1>添加用户</h1>
<form method="POST" action="/user_info/">
<input type="text" name="user"/>
<input type="text" name="pwd"/>
<select name="group_id">
{% for item in group_list %}
<option value="{{item.uid}}">{{item.caption}}</option>
{% endfor %}
</select>
<input type="submit" value="添加"/>
</form> <h1>用户列表</h1>
<ul>
{% for row in user_list%}
<li>
<a href="/userdetail-{{row.id}}">{{row.username}}</a> |
<span>{{row.user_group.caption}}</span>
<a href="/userdel-{{row.id}}/">删除</a> |
<a href="/useredit-{{row.id}}/">编辑</a>
</li>
{% endfor %}
</ul> </div>
</div>
</body>
</html>

user.group.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="height:48px;background-color:black;color:white">
欢迎登陆教育系统
</div>
<div>
<div style="position:absolute;top:48px;bottom:0;left:0;width:200px;background-color:brown;">
<a class="menu" href="/user_info/">用户管理</a>
<a class="menu" href="/user_group/">用户组管理</a>
</div> <div style="position:absolute;top:48px;left:210px;bottom:0;right:0;overflow:auto">
<h1>用户组管理</h1> </div>
</div>
</body>
</html>

user.detail.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="height:48px;background-color:black;color:white">
欢迎登陆教育系统
</div>
<div>
<div style="position:absolute;top:48px;bottom:0;left:0;width:200px;background-color:brown;">
<a class="menu" href="/user_info/">用户管理</a>
<a class="menu" href="/user_group/">用户组管理</a>
</div> <div style="position:absolute;top:48px;left:210px;bottom:0;right:0;overflow:auto">
<h1>用户详细信息</h1>
<h3>{{obj.id}}</h3>
<h3>{{obj.username}}</h3>
<h3>{{obj.password}}</h3>
</div>
</div>
</body>
</html>

user_edit.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="height:48px;background-color:black;color:white">
欢迎登陆教育系统
</div>
<div>
<div style="position:absolute;top:48px;bottom:0;left:0;width:200px;background-color:brown;">
<a class="menu" href="/user_info/">用户管理</a>
<a class="menu" href="/user_group/">用户组管理</a>
</div> <div style="position:absolute;top:48px;left:210px;bottom:0;right:0;overflow:auto">
<h1>编辑用户</h1>
<form method="POST" action="/useredit-{{obj.id}}/">
<input style='display:none' type="text" name="id" value="{{obj.id}}"/>
<input type="text" name="username" value="{{obj.username}}"/>
<input type="text" name="password" value="{{obj.password}}"/>
<input type="submit" value="提交"/>
</form>
</div>
</div>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div style="height:48px;background-color:black;color:white">
欢迎登陆教育系统
</div>
<div>
<div style="position:absolute;top:48px;bottom:0;left:0;width:200px;background-color:brown;">
<a class="menu" href="/user_info/">用户管理</a>
<a class="menu" href="/user_group/">用户组管理</a>
</div> <div style="position:absolute;top:48px;left:210px;bottom:0;right:0;overflow:auto">
<h1>编辑用户</h1>
<form method="post" action="/useredit-{{obj.id}}/">
<input style="display:none" type="text" name="id" value="{{obj.id}}"/>
<input type="text" name="username" value="{{obj.username}}"/>
<input type="text" name="password" value="{{obj.password}}"/>
<input type="submit" value="提交"/>
</form> </div>
</div>
</body>
</html>

目录

本节笔记:

	一对多
A-外键
B-外键字段_id
C-
models.tb.object.create(name='root',user_group_id=1)
D-
userlist=models.tb.object.all()
for row in userlist:
row.id
row.user_group_id
row.user_group.caption
参考出处:http://blog.csdn.net/fgf00/article/details/53678205 

DjangoORM外键操作的更多相关文章

  1. djangoORM 修改表结构/字段/外键操作

    Django支持修改表结构 把max_length=64 改为60 再执行一遍 python manage.py makemigrations python manage.py migrate 如果是 ...

  2. Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)

    Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终 ...

  3. Django(四) ORM 外键操作及初识Ajax

    一.内容回顾 1.Django请求的生命周期: ​ 路由系统 -> 视图函数(获取模板+数据 -> 渲染) -> 字符串返回给用户 2.路由系统: /index/ #-> 函数 ...

  4. Django - orm外键操作

    1.orm外键操作 创建外键: 备注:ForeignKey两个参数,1个为关联的表名,1个为关联的字段名: 在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避 ...

  5. django ORM的外键操作

    外键约束示例 #models操作如下 class HostInfo(models.Model): servername = models.CharField(max_length=) serverip ...

  6. django中的数据库外键操作

    以MYSQL为例: (1)在model中定义两个数据表,食物信息和食物类别信息 class foodInfo(models.Model):     food_id = models.AutoField ...

  7. django 外键操作

    下面定义两个模型,一个主表,一个字表. 举例说明: 如何通过主表对象找到对应的子表对象? 如何通过子表对象找到对应的主表对象? class Person(models.Model); name = m ...

  8. Django-ORM外键属性总结

    ForeignKey ForeignKey(ForeignObject) # ForeignObject(RelatedField) to, # 要进行关联的表名 to_field=None, # 要 ...

  9. DRF 有无外键操作实例

    models.py from django.db import models # Create your models here. class Category(models.Model): &quo ...

随机推荐

  1. CF543E Listening to Music

    题面 空间只有$64\text{MB}$!!! 题解 (据说正解是毒瘤分块套分块) 按照权值从大到小排序,对所有能够覆盖到它的区间的左端点打个标记 按照值域建一棵主席树就可以了 区间查询最大值,用$m ...

  2. CF 987 D. Fair

    D. Fair http://codeforces.com/contest/987/problem/D 题意: n个城镇m条道路,(保证没有重边,两个城镇间可以到达),每个城镇拥有的特产ai(可能多个 ...

  3. ffmpeg 压缩H265 Windows 硬件编码

    硬件NVIDIA:ffmpeg.exe -i input.avi -c:v hevc_nvenc -preset:v fast output.mp4 软件          :ffmpeg.exe - ...

  4. C++操作符优先级带来的错误

    在刷LeetCode题目:190. 颠倒二进制位:颠倒给定的 32 位无符号整数的二进制位时,可以利用左移和右移操作符来实现数字翻转: 错误解法: class Solution { public: u ...

  5. 【UGUI】 (二)--------- 小地图

    在绝大多数游戏中,小地图都是极为常见的一个模块而且十分重要.在Unity里面如何制作一个地图其实也是比较简单的 一. 创建玩家与敌人 创建一个Capsule,命名为Player,代表我们的游戏玩家,创 ...

  6. NO.08--VUE之自定义组件添加原生事件

    前几篇给大家分享了我的业余的“薅羊毛”的经历,回归正题,讲回vue吧: 许多vue新手在工作开发中会遇到一个问题,直接使用 button 添加原生事件是没有问题的,但是使用自定义组件添加原生事件时,就 ...

  7. 使用MyBatis遇到的一些需要记录下的问题

    (1)MyBaits结果集返回Map,Map集合乱序. xml 中的SQL 输出: 改成: 输出: 目测跟字母顺序有关:ABCDEFGHIJKLMNOPQRSTUVWXYZ (2)需要对字段动态排序 ...

  8. docker应用容器化准则—12 factor

    在云的时代,越来越多的传统应用需要迁移到云环境下,新应用也要求能适应云的架构设计和开发模式.而12-factor提供了一套标准的云原生应用开发的最佳原则. 在容器云项目中应用容器化主要参考12-Fac ...

  9. [CF1137]Museums Tour

    link \(\text{Description:}\) 一个国家有 \(n\) 个城市,\(m\) 条有向道路组成.在这个国家一个星期有 \(d\) 天,每个城市有一个博物馆. 有个旅行团在城市 \ ...

  10. 【ML系列】简单的二元分类——Logistic回归

    对于了解机器学习中二元分类问题的来源与分析,我认为王树义老师这篇文章讲的非常好,通俗且易懂: http://blog.sciencenet.cn/blog-377709-1121098.html 但王 ...