Python3基础之学习笔记(十三)-Django文件上传-CBV和FBV-URL-ORM

1. Django

1.2 Django获取多个数据以及文件上传

前端代码

form要加enctype="multipart/form-data"

 
<p>
        <input type="checkbox" name="favor" value="apple">苹果
        <input type="checkbox" name="favor" value="watermelon">西瓜
        <input type="checkbox" name="favor" value="grape">葡萄
    </p>
    <p>
        <select name="city">
            <option value="sh">上海</option>
            <option value="bj">北京</option>
            <option value="tj">天津</option>
        </select>
    </p>
    <p>
        <input type="file" name="myfile" >
    </p>

views.py

        #获取多个内容
        favor=request.POST.getlist('favor',None)
        print(favor)
        #获取文件
        obj=request.FILES.get('myfile')
        #获取文件名
        print(obj.name)
        #保存文件
        import os
        file_name=os.path.join('upload',obj.name)
        f=open(file_name,'wb')
        for data in obj.chunks():
            f.write(data)
        f.close()

1.3 Django的CBV和FBV

CBV指一个url对应一个类,FBV指一个url对应一个函数。

CBV写法

url里写法:

path('home/',views.Home.as_view())

views里写法:

from django.views import View
class Home(View):
    def dispatch(self, request, *args, **kwargs):
        print('before')
        #调用父类的dispatch方法
        result=super(Home,self).dispatch(self, request, *args, **kwargs)
        print('after')
        return result
    def get(self,request):#get请求执行get方法
        pass
    def post(self,request):#post请求执行post方法
        pass
'''
原理是先调用父类dispatch方法来决定是调用get或者post方法
'''

1.4 Django基于正则表达式的URL

2.0以上url写法:

from django.urls import path,re_path
re_path(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html',views.detail,name='detail')

views写法:

def detail(request,nid,uid):
    return HttpResponse(nid,uid)#nid为正则表达式里的数字
#升级版
def detail(request,*args,**kwargs):
    print(request.path_info)#获取当前url,不包含主机名
    from django.urls import reverse
    v=reverse('detail',kwargs={'nid':1,'uid':2})#根据当前url生成新的url
    return HttpResponse(kwargs['nid'])

1.5 Django中URL分发

from django.urls import include, path
 
urlpatterns = [
    path('app1', include('app1.urls')),#如果访问app1先去app1应用下去找urls。
    path('app2', include('app2.urls')),
]

1.6 Django中ORM

1.6.1 创建基本类型及生成数据库

from django.db import models
# Create your models here.
class UserType(models.Model):
    name=models.CharField(max_length=32)
class UserInfo(models.Model):
    username=models.CharField(max_length=30)
    password=models.CharField(max_length=32)
    email=models.CharField(max_length=32)
    user_type=models.ForeignKey(UserType,on_delete=models.CASCADE)
#创建表结构后要用命令同步
# Django 1.6.x 及以下
python manage.py syncdb
# Django 1.7 及以上的版本需要用以下命令
python manage.py makemigrations
python manage.py migrate

1.6.2 使用mysql

修改settings.py

DATABASES={
    'default':{
        'ENGINE':'django.db.backends.mysql',
        'NAME':'dbname',
        'USER''root',
        'PASSWORD':'root',
        'HOST':'127.0.0.1',
        'PORT':'3306',
    }
}

需要修改当前app的 __init__.py

import pymysql
#django默认使用MySQLdb,下面这句话让django使用pymysql
pymysql.install_as_MySQLdb()

1.6.3 基本增删改查

增加数据

def orm(request):
    models.UserInfo.objects.create(
        username='root',
        password='123'
    )
    #另一种方式
    obj=models.UserInfo(username='root',password='123')
    obj.save()
    #第三种方式
    userDict={'username':'root','password':'123'}
    models.UserInfo.objects.create(**userDict)

查找数据

#coding:utf-8
from django.shortcuts import render
from django.http import HttpResponse
from django.http import JsonResponse
from django.forms.models import model_to_dict
from . import models
def orm_query(request):
    #result存取的是对象列表
    result=models.UserInfo.objects.all()
    #限制
    #result=models.UserInfo.objects.filter(username='root')
    #获取第一个数据
    obj=models.UserInfo.objects.filter(username='root').first()
    #获取数据,如果数据不存在抛出异常
    obj=models.UserInfo.objects.get(username='root')
    d=[]
    for row in result:
        print(row.id,row.username,row.password)
        d.append(model_to_dict(row))
    return JsonResponse(d,safe=False)#非字典要设置为False

删除数据

def orm_delete(request):
    #删除所有数据
    models.UserInfo.objects.all().delete()
    #删除指定id
    models.UserInfo.objects.filter(id=1).delete()

更新数据

def orm_update(request):
    #更改所有
    models.UserInfo.objects.update(password='123')
    #更改指定id
    models.UserInfo.objects.filter(id=1).update(password='123')

1.6.4 字段类型介绍

class UserInfo(models.Model):
    username=models.CharField(max_length=32)
    password=models.CharField(max_length=32)
    email=models.CharField(max_length=32,null=True)#数据允许为空
V=models.AutoField(**options)    #int;在Django代码内是自增
 
V=models.DecimalField(max_digits=None, decimal_places=None<, **options>)    #decimal
 
V=models.FloatField(<**options>)    #real V=models.BooleanField(**options)    #boolean或bit
 
V=models.NullBooleanField(<**options>)    #bit字段上可以设置上null值
 
V=models.DateField(<auto_now=false, **options="" auto_now_add="False,">)  #date #auto_now最后修改记录的日期;auto_now_add添加记录的日期
 
V=models.DateTimeField(<auto_now=false, **options="" auto_now_add="False,">)    #datetime
 
V=models.TimeField(<auto_now=false, **options="" auto_now_add="False,">)    #time
 
V=models.TextField(<**options>)    #text
 
V=models.XMLField(schema_path=None<, **options>)    #text ——————————————————————————–
 
V=models.ForeignKey(othermodel<, **options>)    #外键,关联其它模型,创建关联索引
 
V=models.ManyToManyField(othermodel<, **options>)    #多对多,关联其它模型,创建关联表
 
V=models.OneToOneField(othermodel<, parent_link=False, **options>)    #一对一,字段关联表属性

字段列表纵览表

字段名 参数 意义
AutoField 一个能够根据可用ID自增的 IntegerField
BooleanField 一个真/假(true/false)字段
CharField (max_length) 一个字符串字段,适用于中小长度的字符串。对于长段的文字,请使用 TextField
CommaSeparatedIntegerField (max_length) 一个用逗号分隔开的整数字段
DateField ([auto_now], [auto_now_add]) 日期字段
DateTimeField 时间日期字段,接受跟 DateField 一样的额外选项
EmailField 一个能检查值是否是有效的电子邮件地址的 CharField
FileField (upload_to) 一个文件上传字段
FilePathField (path,[match],[recursive]) 一个拥有若干可选项的字段,选项被限定为文件系统中某个目录下的文件名
FloatField (max_digits,decimal_places) 一个浮点数,对应Python中的 float 实例
ImageField (upload_to, [height_field] ,[width_field]) 像 FileField 一样,只不过要验证上传的对象是一个有效的图片。
IntegerField 一个整数。
IPAddressField 一个IP地址,以字符串格式表示(例如: “24.124.1.30” )。
NullBooleanField 就像一个 BooleanField ,但它支持 None /Null 。
PhoneNumberField 它是一个 CharField ,并且会检查值是否是一个合法的美式电话格式
PositiveIntegerField 和 IntegerField 类似,但必须是正值。
PositiveSmallIntegerField 与 PositiveIntegerField 类似,但只允许小于一定值的值,最大值取决于数据库.
SlugField 嵌条 就是一段内容的简短标签,这段内容只能包含字母、数字、下****划线或连字符。通常用于URL中
SmallIntegerField 和 IntegerField 类似,但是只允许在一个数据库相关的范围内的数值(通常是-32,768到**+32,767)**
TextField 一个不限长度的文字字段
TimeField 时分秒的时间显示。它接受的可指定参数与 DateField 和 DateTimeField 相同。
URLField 用来存储URL的字段。
USStateField 美国州名称缩写,两个字母。
XMLField (schema_path) 它就是一个 TextField ,只不过要检查值是匹配指定schema的合法XML。

通用字段参数列表(所有的字段类型都可以使用下面的参数,所有的都是可选的。)

参数名 意义
null 如果设置为 True 的话,Django将在数据库中存储空值为 NULL 。默认为 False 。
blank 如果是 True ,该字段允许留空,默认为 False 。
choices 一个包含双元素元组的可迭代的对象,用于给字段提供选项。
db_column 当前字段在数据库中对应的列的名字。
db_index 如果为 True ,Django会在创建表格(比如运行 manage.py syncdb )时对这一列创建数据库索引。
default 字段的默认值
editable 如果为 False ,这个字段在管理界面或表单里将不能编辑。默认为 True 。
help_text 在管理界面表单对象里显示在字段下面的额外帮助文本。
primary_key 如果为 True ,这个字段就会成为模型的主键。
radio_admin 默认地,对于 ForeignKey 或者拥有 choices 设置的字段,Django管理界面会使用列表选择框()。如果 radio_admin 设置为 True 的话,Django就会使用单选按钮界面。
unique 如果是 True ,这个字段的值在整个表中必须是唯一的。
unique_for_date 把它的值设成一个 DataField 或者 DateTimeField 的字段的名称,可以确保字段在这个日期内不会出现重复值。
unique_for_month 和 unique_for_date 类似,只是要求字段在指定字段的月份内唯一。
unique_for_year 和 unique_for_date 及 unique_for_month 类似,只是时间范围变成了一年。
verbose_name 除 ForeignKey 、 ManyToManyField 和 OneToOneField 之外的字段都接受一个详细名称作为第一个位置参数,可以显示为中文。

1.6.5 简单外键操作

from django.db import models
 
# Create your models here.
class UserGroup(models.Model):
    caption=models.CharField(max_length=30)
    #创建时写入当前时间
    ctime=models.DateTimeField(auto_now_add=True,null=True)
    #更新时写入当前时间
    uptime=models.DateTimeField(auto_now=True,null=True)
class UserInfo(models.Model):
    username=models.CharField(max_length=32)
    password=models.CharField(max_length=32)
    #创建外键在数据库里列名为user_group_id,不是user_group
    #on_delete=models.CASCADE,级联删除默认值。
    user_group=models.ForeignKey('UserGroup',to_field='id',on_delete=models.CASCADE)

查询

def orm_query(request):
    result=models.UserInfo.objects.all()
    for row in result:
         #获取UserInfo里的外键
        print(row.user_group_id)
        #获取外键里的内容
        print(row.caption,row.ctime,row.uptime)      

一对多增加

def orm_add(request):
    models.UserInfo.objects.create(
    username='root',
    password='123',
    user_group_id=1,
    #user_group=models.UserGroup.objects.filter(id=1).first()
    )

1.6.6 创建一对多表结构

创建

from django.db import models
 
# Create your models here.
class Business(models.Model):
    caption=models.CharField(max_length=32)
    #修改表结构
    code=models.CharField(max_length=32,null=True,default='12345678')
class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32,db_index=True)
    ip=models.GenericIPAddressField(db_index=True)
    port=models.IntegerField()
    b=models.ForeignKey(to='Business',to_field='id',on_delete=models.CASCADE)

单表查询的三种方式

from django.shortcuts import render
from . import models
# Create your views here.
def business(request):
    #第一种,得到的是对象列表QuerySet
    v1=models.Business.objects.all()
    #第二种,得到的是字典列表QuerySet
    v2=models.Business.objects.all().values('id','caption')
    #v2=[{'id':'1','caption':'运维'},]
    #第三种,得到的是元组列表QuerySet
    v3=models.Business.objects.all().values_list('id','caption')
    #v3=[(1,'运维'),(2,'市场')]
def host(request):
    pass

跨表查询的三种方式

def host(request):
    #第一种
    v1=models.Host.objects.all()
    #第二种
    v2=models.Host.objects.all().values('hid','hostname','b__caption')
    #第三种
    v3=models.Host.objects.all().values_list('hid','hostname','b__caption')

跨表添加数据

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)
        #                            )
        models.Host.objects.create(hostname=h,
                                   ip=i,
                                   port=p,
                                   b_id=b
                                   )
        return redirect('/host')

1.6.7 创建多对多表结构

第一种方式

#手动创建关系表
from django.db import models
 
# Create your models here.
class Business(models.Model):
    caption=models.CharField(max_length=32)
    code=models.CharField(max_length=32,null=True,default='12345678')
class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32,db_index=True)
    ip=models.GenericIPAddressField(db_index=True)
    port=models.IntegerField()
    b=models.ForeignKey(to='Business',to_field='id',on_delete=models.CASCADE)
class Application(models.Model):
    name=models.CharField(max_length=32)
class HostToApp(models.Model):
    hobj=models.ForeignKey(to='Host',to_field='hid')
    aobj=models.ForeignKey(to='Application',to_field='id')

第二种方式

#自动创建关系表,无法直接操作第三张表
from django.db import models
 
# Create your models here.
class Business(models.Model):
    caption=models.CharField(max_length=32)
    code=models.CharField(max_length=32,null=True,default='12345678')
class Host(models.Model):
    hid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32,db_index=True)
    ip=models.GenericIPAddressField(db_index=True)
    port=models.IntegerField()
    b=models.ForeignKey(to='Business',to_field='id',on_delete=models.CASCADE)
class Application(models.Model):
    name=models.CharField(max_length=32)
    r=models.ManyToManyField('Host')
#第三张表添加
obj=models.Application.objects.get(id=1)
obj.r.add(1)#第三张表里Application_id=1的添加host_id=1
obj.r.add(1,2)
obj.r.add(*[1,2,3,4])
#删除
obj.r.remove(1)
obj.r.remove(1,2)
obj.r.clear()#清空所有Application_id=1
#更新
obj.r.set([3,5,7])
#获取
obj.r.all()#所有相关的QuerySet

没有更多推荐了,返回首页