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')
View Code

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>
View Code

查看结果:

前端页面选择:

查看后台获取的信息:

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})
View Code

 

主站点目录下面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>
View Code

 

显示结果:

 

第三例:页面的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>
View Code

 

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.htmla标签跳转改成下面:

 

<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号

 

posted @ 2016-12-16 00:36  chaishao  阅读(255)  评论(0编辑  收藏  举报