Django ORM 外键操作及初识Ajax

一、内容回顾

1、Django请求的生命周期:

​ 路由系统 -> 视图函数(获取模板+数据 -> 渲染) -> 字符串返回给用户

2、路由系统:

/index/                #->  函数或类.as_view()
/detail/(\d+)          #->  函数(参数) 或 类.as_view()(参数)
/detail/(?P<nid>\d+)   #->  函数(参数) 或 类.as_view()(参数)
/detail/               #->  include("app01.urls")
/detail/    name='a1' #-> include("app01.urls") #-> 视图中:reverse #-> 模板中:{% url "a1" %}

3、视图:

  • FBV:函数

    def index(request,*args,**kwargs):

  • CBV:类

    class Home(views.View):

    ​ def get(self,reqeust,*args,**kwargs):

  • 获取用户请求中的数据:

    request.POST.get
    request.GET.get
    reqeust.FILES.get()
    
    
    # checkbox,select
    
    ........getlist()
  • 文件对象

    文件对象 = reqeust.FILES.get()
    文件对象.name
    文件对象.size
    文件对象.chunks() # 直接循环文件对象也可以 # 特殊的设置 <form action="/login/" method="POST" enctype="multipart/form-data">
  • 给用户返回数据:

    render(request, "模板文件路径", {'k1': [1,2,3,4],"k2": {'name': 'fgf','age': 73}}) redirect("URL") HttpResponse('字符串') 

4、模板语言

render(request, "模板路径", {'obj': 1234, 'k1': [1,2,3,4],"k2": {'name': 'fgf','age': 22}})

<html>
<body> <h1> {{ obj }} </h1> # 取变量值 <h1> {{ k1.3 }} </h1> # 取列表的值 <h1> {{ k2.name }} </h1> # 取字典的值 {% for i in k1 %} # 循环列表的值 <p> {{ i }} </p> # 取值 {% endfor %} {% for row in k2.keys %} # 循环取字典key {{ row }} # 取值 {% endfor %} {% for row in k2.values %} # 循环取字典values {{ row }} # 取值 {% endfor %} {% for k,v in k2.items %} # 循环取key、values {{ k }} - {{v}} # 取值 {% endfor %} # 注意:模板语言循环keys、values、items这里不加 "()" </body> </html>

5、ORM

  • a. 创建类和字段
class User(models.Model):
    age = models.IntergerFiled()            # 整数在后面加长度不起作用 name = models.CharField(max_length=10) # 字符长度 # 生成数据库结构命令 Python manage.py makemigrations python manage.py migrate # settings.py 配置 注册APP
  • b. 操作
# 增
models.User.objects.create(name='qianxiaohu',age=18) # 第一种
dic = {'name': 'xx', 'age': 19} # 第二种 models.User.objects.create(**dic) # **dic obj = models.User(name='xiao',age=18) # 第三种 obj.save() # 删 models.User.objects.filter(id=1).delete() # 改 models.User.objects.filter(id__gt=1).update(name='alex',age=84) dic = {'name': 'xx', 'age': 19} models.User.objects.filter(id__gt=1).update(**dic) # 查 models.User.objects.filter(id=1,name='root') models.User.objects.filter(id__gt=1,name='root')# 大于 models.User.objects.filter(id__lt=1) # 小于 models.User.objects.filter(id__gte=1) # 大于等于 models.User.objects.filter(id__lte=1) # 小于等于 models.User.objects.filter(id=1,name='root') dic = {'name': 'xx', 'age__gt': 19} models.User.objects.filter(**dic) # 这里也可以传字典,增删改查都可以加字典

 

二、Django ORM 外键操作一对多

a.1、创建一对多表结构

class Business(models.Model):
    # id caption = models.CharField(max_length=32) code = models.CharField(max_length=32,null=True,default="SA") # 新增列 允许为空null=True 或 default="SA",就不会提示信息 class Host(models.Model): nid = models.AutoField(primary_key=True) hostname = models.CharField(max_length=32,db_index=True) # 加上索引 ip = models.GenericIPAddressField(protocol="ipv4",db_index=True) port = models.IntegerField() b = models.ForeignKey(to="Business", to_field='id') # 表中生成列名:b_id # b = models.ForeignKey("Business", to_field='id') # 外键约束, # b = models.ForeignKey("Business") #只写表名,默认与那张表主键关联 # 外键: # v = models.Host.objects.filter(nid__gt=0) # v[0].b.caption #----> 通过.进行跨表

 

a.2 获取单表数据的三种方式

  • v1 = models.Business.objects.all() QuerySet类型 ,内部元素都是对象(对象内类似字典结构)
  • v2 = models.Business.objects.all().values('id','caption') QuerySet ,内部元素都是字典 
    • v3 = models.Business.objects.all().values_list('id','caption') QuerySet ,内部元素都是元组
    • ===============
    • models.Business.objects.get(id=1) 获取到的一个对象,如果不存在就报错
    • obj = models.Business.objects.filter(id=1).first() 对象或者None

a.3、示例:展示业务线

urls.py

from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^business$', views.business),
]

 

views.py

from django.shortcuts import render, redirect, HttpResponse
from app01 import models

def business(request): v1 = models.Business.objects.all() # QuerySet # [obj(id,caption,code), obj(id,caption,code), obj(id,caption,code)] v2 = models.Business.objects.values('id','caption') # QuerySet # [{'id':1,'caption':'运维'},{'id':1,'caption':'运维'},{'id':1,'caption':'运维'}] v3 = models.Business.objects.values_list('id','caption') # QuerySet # [(1,运维),(2,开发)] return render(request, "business.html", {'v1':v1,'v2':v2 ,'v3':v3})

 

business.html

<body>
    <h1>业务线列表(对象)</h1> <ul> {% for row in v1 %} <li>{{ row.id }} - {{ row.caption }} - {{ row.code }}</li> {% endfor %} </ul> <h1>业务线列表(字典)</h1> <ul> {% for row in v2 %} <li>{{ row.id }} - {{ row.caption }}</li> {% endfor %} </ul> <h1>业务线列表(元组)</h1> <ul> {% for row in v3 %} <li>{{ row.0 }} - {{ row.1 }}</li> {% endfor %} </ul> </body>

 


b.1、一对多跨表操作

一定要注意:“.”和“__”跨表,在不同场景的应用。

点跨表,点的是对象,双下划线,是在filter里的字符串中。

b.2、一对多块表操作的的三种方式

具体用法看示例,及注释

b.3、示例:host主机列表

urls.py

    url(r'^host$', views.host),

 

views.py

def host(request):
    v1 = models.Host.objects.filter(nid__gt=0) # 同 all() # QuerySet [host 对象,] for row in v1: print(row.nid,row.b_id,row.b.caption,sep='\t') # 注意 row.b.caption 的含义 # 注意:这里通过"__"双下划线跨表。'b__caption' v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','b_id','b__caption') # QuerySet: [ {} ] print(v2) for row in v2: print(row['nid'], row['hostname'],row['b_id'], row['b__caption']) # 注意:这里通过"__"双下划线跨表。'b__caption' v3= models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','b_id','b__caption') # QuerySet: [ () ] b_list = models.Business.objects.all() return render(request, 'host.html', {'v1':v1, 'v2':v2, 'v3':v3, 'b_list':b_list})

 

<body>
    <h1>主机列表(对象)</h1> <table border="1"> <thead> <tr> <th>主机名</th> <th>IP</th> <th>端口</th> <th>业务线名称</th> </tr> </thead> <tbody> {% for row in v1 %} <tr hid="{{ row.nid }}" bid="{{ row.b.id }}"> {# 主机id不需要让用户看见,但修改时又需要,所以自定义个属性#} <td>{{ row.hostname }}</td> <td>{{ row.ip }}</td> <td>{{ row.port }}</td> <td>{{ row.b.caption }}</td> </tr> {% endfor %} </tbody> </table> <hr> <h1>主机列表(字典)</h1> <table border="1"> <thead> <tr> <th>主机名</th> <th>业务线名称</th> </tr> </thead> <tbody> {% for row in v2 %} <tr hid="{{ row.nid }}" bid="{{ row.b.id }}"> <td>{{ row.hostname }}</td> <td>{{ row.b__caption }}</td> </tr> {% endfor %} </tbody> </table> <hr> <h1>主机列表(元组)</h1> <table border="1"> <thead> <tr> <th>主机名</th> <th>业务线名称</th> </tr> </thead> <tbody> {% for row in v3 %} <tr hid="{{ row.0 }}" bid="{{ row.2 }}"> <td>{{ row.1 }}</td> <td>{{ row.3 }}</td> </tr> {% endfor %} </tbody> </table> </body>

c、增加一对多数据示例

如果前端展示序号的话,模板语言for循环那里有几个点可以实现。

{% for row in v1 %}           # 假设3条数据
    {{ forloop.counter}}      # 依次为:1、2、3
    {{ forloop.counter0}}     # 依次为:0、1、2 {{ forloop.revcounter}} # 依次为:3、2、1 {{ forloop.revcounter0}} # 依次为:2、1、0 {{ forloop.last }} # 是否最后一个,是为True,其他False {{ forloop.first }} # 是否第一个 {{ forloop.parentloop }} # 嵌套循环,表示上层循环的上面的六个值分别是多少。 {% endfor %}

 

CSS 知识点position回顾:

  • fixed :生成绝对定位的元素,相对于浏览器窗口进行定位。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。

  • relative :生成相对定位的元素,相对于其正常位置进行定位。因此,”left:20” 会向元素的 LEFT 位置添加 20 像素。

  • absolute :生成绝对定位的元素,相对于第一个父元素进行定位 (static 定位除外外)。元素的位置通过 “left”, “top”, “right” 以及 “bottom” 属性进行规定。


上面的b.3示例,views里host函数,修改为:

def host(request):
    if request.method == "GET": v1 = models.Host.objects.filter(nid__gt=0) v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','b_id','b__caption') v3 = models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','b_id','b__caption') b_list = models.Business.objects.all() return render(request, 'host.html', {'v1': v1,'v2': v2,'v3': v3,'b_list':b_list}) elif request.method == "POST": h = request.POST.get('hostname') i = request.POST.get('ip') p = request.POST.get('port') b = request.POST.get('b_id') models.Host.objects.create(hostname=h, ip=i, port=p, # b=models.Business.objects.get(id=b) # 效果一样,只是多了一次数据库查询操作 b_id=b ) # renturn render(request, 'host.html') # 每次post提交都会有刷新操作 # 使用render需要返回模板数据,if条件里的代码再写一遍,为了提高重用性,让用户再次访问。 return redirect('/host')

 

host.html (部分与上面重复的代码略,行数太多,有些合并为一行了),需要加载jQury。

<head>
    <style> .hide{ display: none; } .shade{ position: fixed; top: 0; right: 0; left: 0; bottom: 0; background: black; opacity: 0.6; z-index: 100; } .add-modal{ position: fixed; height: 300px; width: 400px; margin-left: -200px; top:100px; left: 50%; background: white; border: 1px solid red; z-index: 101; } </style> </head> <body> <h1>主机列表(对象)</h1> <div> <input id="add_host" type="button" value="添加" /> </div> <table border="1"> <thead> <tr> <th>序号</th> <th>主机名</th> <th>IP</th> <th>端口</th> <th>业务线名称</th> </tr> </thead> <tbody> {% for row in v1 %} <tr hid="{{ row.nid }}" bid="{{ row.b_id }}"> <td>{{ forloop.counter }}</td> <td>{{ row.hostname }}</td> <td>{{ row.ip }}</td> <td>{{ row.port }}</td> <td>{{ row.b.caption }}</td> </tr> {% endfor %} </tbody> </table> <div class="shade hide"></div> <div class="add-modal hide"> <form method="POST" action="/host"> <div class="group"> <input id="host" type="text" placeholder="主机名" name="hostname" /> </div> <div class="group"> <input id="ip" type="text" placeholder="IP" name="ip" /> </div> <div class="group"> <input id="port" type="text" placeholder="端口" name="port" /> </div> <div class="group"> <select id="sel" name="b_id"> {% for op in b_list %} <option value="{{ op.id }}">{{ op.caption }}

转载于:https://www.cnblogs.com/weiwu1578/articles/8343664.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值