python基础(十九)
jdango的前端数据传输到后端:
主站目录下的ruls.py添加:
url(r'^zhuce', views.zhuce),
cmdb下的views.py添加:
from django.shortcuts import render from django.shortcuts import HttpResponse from django.shortcuts import redirect from django.core.files.uploadedfile import InMemoryUploadedFile #这个是加载用户上传文件模块
def zhuce(request): if request.method == "GET": return render(request,'zhuce.html') elif request.method == "POST": v = request.POST.get('gender') #get只能获取一个值 f = request.POST.getlist('favor') #getlist才可以获取多个值 c = request.POST.get('city') c2 = request.POST.getlist('city2') ff = request.POST.get('fafile') #这个只能获取字符串,但是当前端html页面以文件形式传输时这里就获取不到值了。 print(v,f,c,c2,ff) obj = request.FILES.get('fafile') #获取文件 print(obj,type(obj),obj.name)#obj是文件,看类型就不单单是文件名,obj.name为文件名 f = open(obj.name,mode="wb")#打开一个文件进行文件接收 for i in obj.chunks(): #chunks是把文件分块,数据本来就是一块块的进行传输的 f.write(i) f.close() return render(request,'zhuce.html')
templates目录下添加html页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/commons.css" /> <style> label{ width: 80px; text-align: right; display: inline-block; } </style> </head> <body> <form action="/zhuce" method="post" enctype="multipart/form-data"> #enctype="multipart/form-data"加上这句话就是文件以文件形式传输到后台,不然只是把文件名称传过去 <p> <input type="text" name="user" placeholder="用户名" /> </p> <p> <input type="password" name="pwd" placeholder="密码" /> </p> <p> 男:<input type="radio" name="gender" value="1" /> 女:<input type="radio" name="gender" value="2"/> 人妖: <input type="radio" name="gender" value="3" /> </p> <p> 篮球:<input type="checkbox" name="favor" value="1"> 足球:<input type="checkbox" name="favor" value="2"> 排球:<input type="checkbox" name="favor" value="3"> </p> <p> <select name="city"> #单选下拉列表 <option value="sh">上海</option> <option value="bj">北京</option> <option value="tj">天津</option> </select> </p> <p> <select name="city2" multiple> #多选下拉列表 <option value="sh">上海</option> <option value="bj">北京</option> <option value="tj">天津</option> </select> </p> <p> <input type="file" name="fafile"> </p> <p><input type="submit" value="提交"></p> </form> <script src="/static/jquery.min.js"></script> </body> </html>
查看结果:
前端页面选择:
查看后台获取的信息:
2 ['1', '2'] bj ['bj', 'tj'] None
jquery-migrate-1.4.1.min.js <class 'django.core.files.uploadedfile.InMemoryUploadedFile'> jquery-migrate-1.4.1.min.js
另外,如果要上传到其他目录,在views.py里面修改代码为:
import os file_path = os.path.join('upload',obj.name) #在制定文件前面加上上传目录位置 f = open(file_path,mode="wb")
注:
客户端发来请求发到服务端,有请求头,请求尾,服务端会根据请求头里的信息做提取,django会把表单这些内容提取到POST中,把文件提取到FILE中
二、路由系统的URL
第二个例子:后台传参到前端,前端for循环输出信息
cmdb目录下的views.py的设置:
USER_DICT = { '1':{'name':'root1','email':'root@live.com'}, '2':{'name':'root2','email':'root@live.com'}, '3':{'name':'root3','email':'root@live.com'}, '4':{'name':'root4','email':'root@live.com'}, } USER_LIST = [ {'name':'root'}, {'name':'root'}, {'name':'root'}, ] def index(request): return render(request,'index.html',{'user_dict':USER_DICT})
主站点目录下面urls.py:
url(r'^index/',views.index),
Templates目录下的index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for k in user_dict.keys %} <li> {{ k }} </li> {% endfor %} </ul> <ul> {% for val in user_dict.values %} <li> {{ val }} </li> {% endfor %} </ul> <ul> {% for k,row in user_dict.items %} <li> {{ k }}-{{ row }} </li> {% endfor %} </ul> </body> </html>
显示结果:
第三例:页面的url实现根据nid跳转
Templates目录下的index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <ul> {% for k,val in user_dict.items %} <li> <a target="_blank" href="/detail/?nid={{ k }}">{{ val.name }}</a> #target在新窗口中打开链接,href="/detail/?nid={{ k }}跳转到url/detail/?nid=k的连接,{{ val.name }}点击val里面的k值是name的值 </li> {% endfor %} </ul> </body> </html> Detail.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>详细信息</h1> <h6>用户名:{{ detail_info.name }}</h6> <h6>用户邮箱:{{ detail_info.email }}</h6> </body> </html>
views.py下的设置:
def detail(request): nid = request.GET.get('nid') #获取前台页面nid的值 detail_info = USER_DICT[nid] #USER_DICT键值前台页面传过来的nid的val值 return render(request,'detail.html',{'detail_info':detail_info})
Urls.py:
url(r'^detail/',views.detail),
查看结果:
例子三:
如果不喜欢http://127.0.0.1:8000/detail/?nid=4这种?号的链接形式,换一种静态URL的方式
views.py里面设置:
def detail(request,nid): print(nid) #这里可以不写,主要是看下urls传过来的值 detail_info = USER_DICT[nid] return render(request,'detail.html',{'detail_info':detail_info})
Urls.py改成下面:
url(r'^detail-(\d+).html',views.detail),
Index.html的a标签跳转改成下面:
<a target="_blank" href="/detail-{{ k }}.html">{{ val.name }}</a>
显示结果:
注:但是如果要传两个参数呢?
#url(r'^detail-(\d+)-(d+).html',views.detail), #这种不推荐,这是死的,只会把第一个参数传给views里面第一个
url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html',views.detail), #这种是比较灵活的,不管views里面nid和uid位置的设定,这里只会把第一个接收的值赋值给nid,第二个接收的值赋值给uid
views.py里面设置:
def detail(request,uid,nid): #第一个是uid,第二个是nid,估计把两个的位置颠倒一下 print(nid,uid) detail_info = USER_DICT[nid] return render(request,'detail.html',{'detail_info':detail_info})
查看结果:
例子四:Django里面一个独有的特性:
url(r'^index/',views.index),
url(r'^indexxxxxx/',views.index,name='indexx'), #给这个url定义一个名称indexx,以后url再发生变化,前台的html页面action哪里就不用跟着进行修改了。
Index.html
<form action="{% url 'indexx' %}" method="POST"> #直接引用名称
查看结果:
如果加入nid呢?
加入nid
url(r'^indexxxxxx/(\d+)/',views.index, name='indexx'), #如果加入了/数字nid的传递
Views.py里面的设置:
def index(request,*args):
return render(request,'index.html',{'user_dict':USER_DICT})
Index.html里面的设置:
<form action="{% url 'indexx' 3 %}" method="POST">
#里面的数值只能是一个固定的值,就是访问不通的url提交到另一个指定的固定的地方
例子五:访问什么页面就提交什么页面的形式
url(r'^index/(\d+)',views.index),
Views.py里面的设置:
def index(request,nid):
print(request.path_info) #这里可以不需要,但是这里主要是request.path_info通过这个来获取访问的页面
return render(request,'index.html',{'user_dict':USER_DICT})
Index.html:
<form action="{{ request.path_info }}" method="POST"> #直接调用这个request.path_info
对URL路由关系进行命名, ***** 以后可以根据此名称生成自己想要的URL *****
url(r'^asdfasdfasdf/', views.index, name='i1'),
url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'),
url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),
例子六、多nid传参的形式:
url(r'^index/(?P<nid>\d+)/(?P<uid>\d+)/',views.index),
url(r'^indexxxxxx/(?P<nid>\d+)/(?P<uid>\d+)/',views.index, name='indexx'),
Views.py:
def index(request,nid,uid):
#v = reverse('indexx', args=(90,88,)) #也可以这样搞
v = reverse('indexx', kwargs={"nid":1, 'uid': '99'}) #因为传过来的是两个值,可以这样定义一下
print(v)
return render(request,'index.html',{'user_dict':USER_DICT})
Index.html:
<form action="{% url 'indexx' nid=1 uid=3 %}" method="POST">
例子七:url路由分类,include路由分发
主站目录下面:
urls.py:
from django.conf.urls import include
urlpatterns = [
url(r'^cmdb/',include("cmdb.urls")), #分发到cmdb下的urls
url(r'^openstack/',include("openstack.urls")), #分发到openstack下的urls
]
cmdb下的urls: from django.conf.urls import url,include from django.contrib import admin from cmdb import views urlpatterns = [ url(r'^login/',views.login), ] cmdb下的views.py: from django.shortcuts import HttpResponse def login(request): return HttpResponse('cmdb,login')
效果展示:
例子八、配置django调用mysql
主站的settings.py: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'django', #数据库名称需要提前创建 'USER': 'root', 'PASSWORD': '123456', 'HOST': '192.168.1.108', 'PORT': '3306', } } INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'cmdb', #就是这里,如果我们在cmdb下面配置了modles.py要在这里添加 ]
主站的__init__.py里面:
import pymysql #因为python3还不支持,所以要用pymysql
pymysql.install_as_MySQLdb()
cmdb目录下面的models.py:
from django.db import models # Create your models here. class UserInfo(models.Model): #继承models.Model,必须继承,定义了一个UserInfo类,创建的表名称也会为cmdb_userinfo #id,自增,主键,隐藏的,如果不加也自动加上这列 #id是隐藏的会自己添加的字段 #创建用户名列,字符串类型,指定长度 username = models.CharField(max_length=32) password = models.CharField(max_length=64)
在Terminal上面运行:
python manage.py makemigrations
python manage.py migrate
例子八、django对数据库的增删改查
数据库增加字段操作:
cmdb目录下面的views.py:
from cmdb import models #引入cmdb下的models def orm(request): models.UserInfo.objects.create(username='root',password='123') #这是给UserInfo类,也就是给cmdb_userinfo表增加字段操作,推荐使用这种 #dic = {'username':'eric','password':'666'} #这是一种变种 #models.UserInfo.objects.create(**dic) #obj = models.UserInfo(username='alex',password='123') 这是另外一种方式 #obj.save() return HttpResponse('orm')
基本的查询操作:
result = models.UserInfo.objects.filter(username='alex',password='123456') #这相当于双重条件匹配 #result = models.UserInfo.objects.filter(username='alex') #过滤查找用户名为root的列 #result = models.UserInfo.objects.all() #all()查找所有 #result返回的是QuerySet类型,是django提供的,可以理解为一个[]列表 #[obj(id.username,password),obj(id.username,password),obj(id.username,password)] for row in result: #result可以是多列,所以要写for循环, print (row.id,row.username,row.password) # print(result)
基本的删除操作:
#models.UserInfo.objects.all().delete() #删除所有字段 models.UserInfo.objects.filter(username='eric').delete() #基于什么条件删除 return HttpResponse('orm')
数据库表修改:
增加列操作:
models.py里面的配置
from django.db import models # Create your models here. class UserInfo(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=64) email = models.CharField(max_length=64) #后加入此列 gender = models.CharField(max_length=64,null=True) #后加入此列,null=True,允许为空 #email = models.EmailField(max_length=64) #注释掉就代表去除这一列,EmailField在admin管理的时候,提交的时候检查是否是制定格式。
特殊的是: uid = models.AutoField(primary_key=True) #AutoField是自增的,要加上primary_key=True 字段的参数: null -> db是否可以为空 default -> 默认值 primary_key -> 主键 db_column -> 列名 db_index -> 索引 unique -> 唯一索引 unique_for_date -> 只对时间做索引 unique_for_month -只对月份做索引 unique_for_year -->只对年份做索引 auto_now -> 创建时,自动生成时间 auto_now_add -> 更新时,自动更新为当前时间 # obj = UserGroup.objects.filter(id=1).update(caption='CEO') # obj = UserGroup.objects.filter(id=1).first() # obj.caption = "CEO" # obj.save() #下面这些都是django-admin的: choices -> django admin中显示下拉框,避免连表查询 blank -> django admin是否可以为空 verbose_name -> django admin显示字段中文 editable -> django admin是否可以被编辑 error_messages -> 错误信息欠 help_text -> django admin提示 validators -> django form ,自定义错误信息(欠) test = models.EmailField(max_length=19,null=True,error_messages={'invalid': '请输入密码'}) #当用户什么都没有填的时候提示:请输入密码
#插入语句小例子,自动创建时间戳
Models.py:
class UserGroup(models.Model): uid = models.AutoField(primary_key=True) caption = models.CharField(max_length=32,unique=True) ctime = models.DateTimeField(auto_now=True,null=True) uptime = models.DateTimeField(auto_now=True,null=True)
obj = UserGroup.objects.filter(id=1).update(caption='CEO') #这种更新uptime的更新是不生效的,jdango不支持,支持下面的形式
obj = UserGroup.objects.filter(id=1).first() #这种uptime时间才会发生变化
obj= "CEO"
obj.save()
user_type_choices = (#这几个选项会放到内存里面,而在数据库里面生成的时候只是数字 (1, '超级用户'), (2, '普通用户'), (3, '普普通用户'), ) user_type_id = models.IntegerField(choices=user_type_choices,default=1)
根据类对数据库表中的数据进行各种操作:
user_group = models.ForeignKey("UserGroup",to_field='uid',default=1)
#ForeignKey外键关联 "UserGroup"将这个表关联过来 to_field='uid' #与uid字段相关联 ,default=1 #数字也就是uid号