DjangoORM外键操作

Posted momo8238

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 

 

以上是关于DjangoORM外键操作的主要内容,如果未能解决你的问题,请参考以下文章

Django ORM 数据库操作

djangoORM 通过外键字段找对应类

Django入门4: ORM 数据库操作

DjangoORM训练专题

DjangoORM多表实例

DjangoORM多表实例