DjangoORM外键操作
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