Django后续

环境准备

建立一个Django项目,可使用前面使用命令行建立,在这里我是使用pycharm建立的。css

记得选择左边的Django,Location建立项目的目录最后一级为项目的名称。在这里咱们能够建立一个app,如上如我建立了app01。html

建立好后咱们能够看见一个目录为:python

咱们须要在这个目录的manager.py同级目录建立一个static的静态目录,用来放置css,和js。mysql

再日后咱们须要在setting.py的配置文件作如下配置:正则表达式

  • 找到 'django.middleware.csrf.CsrfViewMiddleware'并把它注释掉
  • 找到TEMPLATES部分,若是没有以下代码,则须要添加:'DIRS': [os.path.join(BASE_DIR, 'templates')]
  • 在文件的最后添加静态文件目录,这里须要注意这里面是一个元组,因此注意要有逗号(,)。

到这里咱们的一些基本的配置就配好了。最后咱们获得的目录为sql

上面就是咱们开始Django项目前的一些环境准备。数据库

 

下面是一个简单的登陆验证的页面

大体能够写以下3步:django

  • 在myobj下的urls.py里面写下相应的路有关系
  • 在app01目录下面咱们写相关的业务代码,也就是写相应的视图函数
  • 在写相应的html

上面在咱们写相应的路由关系的时候,咱们须要把把路由关系和视图函数联系起来session

写法如图:加上红色的那一句oracle

第一步就是写相关的路由关系

from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^index/', views.index),
]

 

写好后咱们在写对应的视图函数、视图函数在app01下面的views里面写代码以下

from django.shortcuts import render,redirect
# Create your views here.
def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
       if user == 'admin' and pwd == 'admin':
            return redirect('/index/')
        else:
            return render(request,'login.html')
    else:
        return render(request,'login.html')

def index(request):
    return render(request,'index.html')

 

 在接下来写index和login相关的代码

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login/" method="post" enctype="multipart/form-data">
        <p><input type="text" name="user" placeholder="请输入用户名"/></p>
        <p><input type="password" name="pwd" placeholder="请输入密码"/></p>
        <p><input type="submit" value="登录"></p>
    </form>
    </div>
</body>
</html>

 

index.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>登录成功</div>
</body>
</html>

 

 记住上面的这些HTML代码都是放在templates目录下面的。而static目录里面放的是一些js和css文件

上面咱们能够看到

这个就是登陆界面,当咱们输入的用户名和密码正确的时候就会跳转到咱们成功的页面,当咱们失败的时候还会停留在这个页面。

 

获取数据和文件上传

在视图里面(/app01/views.py)
    1、获取用户请求数据
        request.GET.get(标签里面的name属性值)   
        request.POST.get(标签里面的name属性值)
        request.FILES.get(标签里面的name属性值)
        PS:
            GET:获取数据                
            POST:获取用户提交数据
            
    2、获取checkbox等多选的内容
        request.POST.getlist(标签里面的name属性值)
    3 、上传文件
          # 上传文件,form标签作特殊设置
        obj = request.FILES.get('fafafa')
        obj.name
        f = open(obj.name, mode='wb')
        for item in obj.chunks():
            f.write(item)
        f.close()

 

上面使用标签里面的name属性值获取到的是标签里面value属性值。

关于获取checkbox等多选的内容实验

视图里面的代码(/app01/views.py)

from django.shortcuts import render,redirect,HttpResponse
from django.views import View
import os
# Create your views here.
def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == "POST":
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        gender = request.POST.get('gender')
        favor = request.POST.getlist('favor')
        city = request.POST.getlist('city')
        print(user,pwd,gender,favor,city)
        obj = request.FILES.get('upload')
        print(obj,type(obj),obj.name)
        file_path = os.path.join('upload_dir',obj.name)
        with open(file_path, 'wb') as f:
            for i in obj.chunks():
                f.write(i)
        return HttpResponse('ok')
# 打印的结果
#admin admin 1 ['1', '2', '3'] ['sh', 'bj', 'tj']
#2018-07-04日22:00 巡检记录.txt <class 'django.core.files.uploadedfile.InMemoryUploadedFile'> 2018-07-04日22:00 巡检记录.txt

 

login.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login/" method="post" 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">
    </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" multiple>
            <option value="sh">上海</option>
            <option value="bj">北京</option>
            <option value="tj">天津</option>
        </select>
    </p>
    <p>
        <input type="file" name="upload">
    </p>
    <input type="submit" value="提交">
</form>
</body>
</html>

 从上面咱们能够知道咱们经过标签里面的name属性值获取到的是标签的value,当时多选的时候会获得一个列表。

同时上传文件咱们获得的是一个obj咱们打印出这个obj看到的是一个上传文件的名字,可是经过type能够知道这个并不仅是一个文件名。

要想获取里面文件里面的数据咱们使用obj.chunks()的方法获取里面数据,经过和操做文件句柄同样的操做一行行的读取里面的数据再把这个数据写入到文件中,记住使用'wb'的方式,这个上传的多是图像

经过obj.name获取到咱们真正想知道的文件名。上面上传文件咱们须要提早建立一个upload_dir目录要不就会报错。

写视图的方式有FBV和CBV

一、FBV

FBV --> function base view

这个写视图用的是函数的方式。

如:

def  函数名(request):

同时写路由关系就是上面的方式:

from app01 import views

url(r'^login/', views.login)

 二、CBV

CBV --> class base view

使用类的方式写视图。

这里的类须要继承View类,因此咱们在视图函数里面须要导入

from django.views import View

class 类名(View):

写路由关系咱们须要在路由关系中写:

记住在视图类的后面要加上.as_view(),下面黄色部分使咱们能够变化的路由关系

url(r'^login/', views.Login.as_view())

 

咱们上面就是使用的FBV写的,如今咱们使用CBV实现下登陆页面的验证

先在myobj/urls.py里面代码

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^index/', views.Index.as_view()),
    url(r'^login/', views.Login.as_view()),

]

 

视图里面的代码

from django.shortcuts import render,redirect
from django.views import View
class Index(View):
    def get(self,request):
        return render(request,'index.html')

class Login(View):
    def get(self,request):
        return render(request,'login.html')
    def post(self,request):
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'admin' and pwd == 'admin':
            return redirect('/index/')
        else:
            return render(request,'login.html')

 

html代码和上面的第一个登陆界面的html代码是同样的没什么区别。这个实现后的效果也是同样的。只是不一样形式的实现方式这个是CBV的方式实现的。

简单分析CBV的运行的流程

咱们直接访问页面的时候通常都是使用get的方式提交的

当咱们输入url他会在路由关系里面找到相应的视图类,咱们使用继承的类的里面使用了反射函数。

咱们能够经过看继承的父类里面的代码能够知道它里面是帮咱们作了相应的处理,反射到咱们在类里面绑定的函数。

直接执行咱们在内中绑定的函数。就实现了整个流程。

 视图中传入模板的字典数据的循环取值

卸载app01/views.py中的代码

from django.shortcuts import render
USER_DICT = {
    "k1":"root1",
    "k2":"root2",
    "k3":"root3",
    "k4":"root4",
    "k5":"root5",
}

def index(request):
    return render(request,"index.html",{"user_dict":USER_DICT})

 

index.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for k,row in user_dict.items  %}
            <li>{{ k }}-{{ row }}</li>
        {% endfor %}
        {% for k in user_dict %}
            <li>{{ k }}</li>
        {% endfor %}
        {% for v in user_dict.values %}
            <li>{{ v }}</li>
        {% endfor %}
    </ul>
</body>
</html>

上面咱们能够看到我么你能够经过for循环dict.items取字典的键值对

也能够经过for循环dict.values取字典的每个值,也能够直接循环字典获得字典的键。

 

Django的路由系统

多级路由

上面写的都是经过主urls文件经过导入app的views来实现关于路由到视图的关联,也能够称主usrl文件为一级路由

当咱们外部访问的时候,会在一级路由中查找,若是想要多级路由就要在以及路由里面导入下一级路由。

代码为:

from django.conf.urls import url, include

urlpatterns = [
    url(r'^cmdb/', include("app01.urls")),  
]

上面的urls咱们须要在app01下面本身建立。

先说一下当咱们输入url的时候在路由系统里面咱们匹配的去除掉前面域名的

如:http://127.0.0.1/cmdb/django/,咱们只会匹配后面/cmdb/django

在一级路由的时候咱们会正则匹配/cmdb/同时也去除掉前面正则匹配的这时只有/django/那会拿着这个url到app01里面的urls里面正则匹配相应的路由。这样就实现了多级路由。咱们能够认为只要前面是/cmdb/咱们就会把剩下的路由传递给include的下一级路由。这个就是多级路由

 url()方法

url()方法能够接受4个参数(regex, view, kwargs=None, name=None)能够看出2个是必须的

regex:这个就是正则表达式的缩写,这个就是匹配字符串或这url地址的语法。

view:指的是处理当前url请求的试图函数。

kwargs:任意数量的关键字参数能够做为一个字典传递给目标视图

name:对你的URL进行命名,让你可以在Django的任意处,尤为是模板内显式地引用它。这是一个很是强大的功能,至关于给URL取了个全局变量名,不会将url匹配地址写死。

这里只是简单的介绍一下这四个参数。

regex

关于regex的写法,当一个网站的url地址太多的时候咱们就会写的太多。咱们能够把一些有相同特性的url写成赞成格式:

如:url(r'^index-(\d+).html', views.index),这个就是一个正则表达式,能够匹配这一类型的url

或者url(r'^index-(\d+)-(\d+).html', views.index),这个能够更好的匹配相应的url

上面的这个匹配会把分组的匹配到的按位置传送到view试图函数。至关于他会把第一个分组匹配的看成视图函数的一个参数传给试图函数,

这个若是参数的位置写错了就会形成后面的一系列数据错误,因此不推荐使用这个。

咱们可使用:url(r'^index-(?P<nid>\d+)-(?P<uid>\d+).html', views.index)

这个就是正则的给分组起一个名字,这样咱们就会获得一个字典咱们就能够把这个字典传到视图函数里面。

这样咱们就能够根据咱们起的名字来取到咱们想要的数据。

视图函数能够是:def 函数名(request,*args,**kwargs):pass

这样无论咱们url里面的分组是否起名字咱们都可以传到后面。不过建议使用后一种方式这样不容易出错。

name

name是对URL路由关系进行命名,之后能够根据此名称生成本身想要的URL

url(r'^asdf/', views.index, name='i1'),

url(r'^qwe/(\d+)/(\d+)/', views.index, name='i2'),

url(r'^asd/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),

这个样咱们在视图函数里面能够:

from django.urls import reverse        

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

  url1 = reverse('i1')                # 获得的是  asdf/

  url2 = reverse(‘i2',args(1,2))          # 获得 /qwe/1/2

  url3 = reverse('i3',kwargs{pid:1,nid:3})   # asd/1/3

在模板语言中:

{% url "i1" %}    ---生成/asdf/

{% url "i2" 1 2 %}  --生成qwe/1/2/

{% url "i3" pid=1 uid=3 %} ---生成asd/1/3/

这个的用处好比咱们本来有一个网址咱们如今改成一个新的网址,可是由于旧的网址,用的人比较多咱们就能够利用跳转

如:

原来的:

url(r'^qwe/(\d+)/(\d+)/', views.index),

改为

url(r'^new_qwe(\d+)/(\d+)/', views.new_index,name='i1'),

咱们只须要在view里面增长

from django.http import HttpResponseRedirect

from django.urls import reverse

def inde(requsrt,a,b):

  return HttpResponseRedirect(reverse('i1',args=(a,b)))

Django的ORM

一、数据库的安装

再说ORM的时候,咱们先说一下数据库的安装。

咱们打开项目的setting.py的配置文件,这个是整个个Django项目的设置中心。Django默认使用SQLite数据库,由于Python源生支持SQLite数据库,因此你无须安装任何程序,就能够直接使用它。固然,若是你是在建立一个实际的项目,可使用相似PostgreSQL的数据库,避免之后数据库迁移的相关问题。

在这个配置文件中咱们能够找到以下的代码,这个就是默认的数据库配置,这个默认为SQLite数据库。

# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

 

若是咱们想要其余的数据库的时候咱们能够在上面的key为default对应的值进行配置。来链接你的数据库。上面的一些参数的解释

ENGINE(引擎):能够是django.db.backends.sqlite3django.db.backends.postgresqldjango.db.backends.mysqldjango.db.backends.oracle等其余的

NAME(名称):相似Mysql数据库管理系统中用于保存项目内容的数据库的名字。若是你使用的是默认的SQLite,那么数据库将做为一个文件将存放在你的本地机器内,此时的NAME应该是这个文件的完整绝对路径包括文件名,默认值os.path.join(BASE_DIR, ’db.sqlite3’),将把该文件储存在你的项目目录下。

下面就是一个使用mysql数据库的,由于python不支持mysql因此只能借助pymysql来实现操做mysql

import pymysql         # 必定要添加这两行
#  这个pymysql不属于python内置的须要咱们本身安装
pymysql.install_as_MySQLdb()

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

 

咱们在操做数据库的时候,咱们必须如今mysql中建立相应的数据库才能操做。

还有在我本身建立的app时咱们须要把这个app加入到setting中,若是是用pycharm建立Django项目是就穿件的就不须要

使用命令建立的就须要加入:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',  # 把咱们建立的app01加入
]

 

二、建立类

 咱们在相应的app中的models.py里面建立咱们想要的模型,在这里面咱们全是用python代码实现的不接触任何的SQL语句

app01/models.py

from django.db import models

class UserInfo(models.Model):
    # Django会默认建立一个id列,而且是自增,主键
    # 用户名列,字符串类型,指定长度
    username = models.CharField(max_length=32)
    # 密码列,字符类型,指定长度
    password = models.CharField(max_length=64)

 

 这样建立模型后,咱们须要执行相应的代码才能把这些写到相应的数据库中,也就是启动模型。

Django会作2件事。

一、建立app对应的数据库表结构

二、为咱们模型里面的对象建立基于python的数据库访问API

这个执行的目录就是manage.py同目录下面。

在命令行:python3 manage.py makemigrations

经过运行makemigrations命令,至关于告诉Django你对模型有改动,而且你想把这些改动保存为一个“迁移(migration)”。

migrations是Django保存模型修改记录的文件,这些文件保存在磁盘上。在例子中,它就是app01/migrations/0001_initial.py,你能够打开它看看,里面保存的都是人类可读而且可编辑的内容,方便你随时手动修改。

 这里还须要咱们把数据迁移到数据库里面就还须要执行

python3 manage.py migrate

这里面由于默认为SQLite,要想查看里面的数据咱们可使用Navicat Premium 12这个软件链接到SQLite

也能够直接在pycharm上查看。

 

 点击pycharm右面的有一个database而后就有上面的画面,再把咱们和manage.py同目录上面的db.sqlite3拖到这个框框里面

从上面能够看出咱们可以对数据库进行相应的操做了。

上面就是在django里面模型的建立以及把模型迁移到数据库上的操做,以及查看的一些方式。

三、添加数据

使用python语句添加数据的几种方式

1、

models.UserInfo.objects.create()

from django.shortcuts import HttpResponse
from app01 import models
def orm(request):
    models.UserInfo.objects.create(username='root', password='1234')
    return HttpResponse('ok')

 

 当咱们访问http://127.0.0.1:8000/orm/的时候咱们就会在数据库里面建立该数据

注意这里咱们在urls的路由系统里面加了相应的路由配置

2、

obj = models.UserInfo()

obj.save()

from django.shortcuts import HttpResponse
from cmdb import models
def orm(request):
    obj = models.UserInfo(username='admin', password='1234')
    obj.save()
    return HttpResponse('ok')

  当咱们访问http://127.0.0.1:8000/orm/的时候咱们就会在数据库里面建立该数据

3、

这种方式就是第一种的差很少只是咱们传进去的是一个字典

from django.shortcuts import HttpResponse
dic = {
    'username':'qwer',
    'password':'1234'
}
# Create your views here.
from cmdb import models
def orm(request):
    models.UserInfo.objects.create(**dic)
    return HttpResponse('ok')

 

上面的字典中的key就是咱们数据库中的列,值就是列中对应的数据。

四、数据库数据的查询

查询全部:ret = models.UserInfo.objects.all()

这里获得的返回值为:<QuerySet [<UserInfo: UserInfo object (1)>, <UserInfo: UserInfo object (2)>, <UserInfo: UserInfo object (3)>]>

上面能够知道咱们获得一个QuerySet数据这个和列表有点相似,咱们能够经过循环获取它的数据

from django.shortcuts import render
from django.shortcuts import HttpResponse
# Create your views here.
from cmdb import models
def orm(request):
    ret = models.UserInfo.objects.all()
    print(ret)
    for row in ret:
        print(row)
        print(row.id,row.username,row.password)
    return HttpResponse('ok')
## 结果
<QuerySet [<UserInfo: UserInfo object (1)>, <UserInfo: UserInfo object (2)>, <UserInfo: UserInfo object (3)>]>
UserInfo object (1)
1 root 1234
UserInfo object (2)
2 admin 1234
UserInfo object (3)
3 qwer 1234

 

能够看出ret是一个QuerySet数据类型,循环咱们获得的是一个object对象,咱们能够经过object对象获取相应的数据。

 

条件语句查询:result =models.UserInfo.objects.filter(username="root")

查询username为root的用户全部信息至关于数据库的where username = 'root'

这个查询出来的也是QuerySet类型的

from django.shortcuts import HttpResponse
# Create your views here.
from cmdb import models
def orm(request):
    ret = models.UserInfo.objects.filter(username='root')
    print(ret)
    print(ret[0].username)
    return HttpResponse('ok')

#结果为
<QuerySet [<UserInfo: UserInfo object (1)>]>
root

 

上面咱们能够看出查询出来的仍是QuerySet数据类型,

五、删除数据

models.UserInfo.objects.delete() 删除全部数据

models.UserInfo.objects.filter(id=2).delete() 经过条件删除

六、更新数据

models.UserInfo.objects.all().update(password=222)    #将全部的的密码都更改,

models.UserInfo.objects.filter(id=2).update(password=888)  # 根据条件更新

ORM的一些补充

建立数据库表的有哪些字符类型中的字段的参数的意思

null               -> db是否能够为空default            -> 默认值primary_key        -> 主键db_column          -> 列名db_index           -> 索引unique          -> 惟一索引unique_for_date    -> unique_for_monthunique_for_yearauto_now           -> 建立时,自动生成时间auto_now_add       -> 更新时,自动更新为当前时间choices            -> django admin中显示下拉框,避免连表查询blank             -> django admin是否能够为空verbose_name      -> django admin显示字段中文editable          -> django admin是否能够被编辑help_text         -> django admin提示...
相关文章
相关标签/搜索