Python之路-(Django进阶一)

Django请求生命周期:

  首先,客户端发送请求到服务器的urls库,通过匹配url后面的关键字,去找指定app里面的的view。

  然后,app通过判断,拿到数据库数据和html模板文件。

  最后,将拿到的数据发送到客户端。

 

Django获取html里面数据:

  前面我们说了,通过判断request.method == "POST"。request.POST.get获取数据。这样只能获取单个数据。

  request.POST.getlist('name'),例如checkbox复选框和下来菜单。

  文件上传:

def login(request):
    if request.method == "GET":
        return  render(request,"login.html")
    elif request.method == "POST":
        obj = request.FILES.get("tijiao")
        print(obj,type(obj),obj.name)
        import os
        file_path = os.path.join('upload',obj.name)
        f = open(file_path,mode="wb")
        for i in obj.chunks():
            f.write(i)
        f.close()
        return render(request,'login.html')
    else:
        return redirect('/index/')
View Code
<!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"/>
            张扬:<input type="radio" name="gender" value="3"/>
        </p>
        <p>
            男:<input type="checkbox"  name="favor" value="11"/>
            女:<input type="checkbox" name="favor" value="22"/>
            张扬:<input type="checkbox" name="favor" value="33"/>
        </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="tijiao"/>
        </p>

        <input type="submit" value="提交"/>
    </form>
</body>
</html>
View Code

 

Django的CBV和FBV:

  function base views(FBV):

  urls.py

    index -->函数名

    views.py--def 函数(request):

            ........

  class base views(CBV):

    index --> 函数名

    index -->类

from django.views import View
    class home(View):
        def get(self,request):
            pass
        def post(self,request):
            pass
还有一个地方需要更改。
    django项目里的urls.py在写路由关系时候需要这么写。
    url(r'^home/', views.home.as_view()),

示例:

我们知道,在执行class里面的get或post方法时候,首先是在一个dispatch里面反射找到我们定义的方法,

class Home(View):
    def dispatch(self, request, *args, **kwargs):
        # 调用父类中的dispatch
        print("before")
        result = super(Home,self).dispatch(request, *args, **kwargs)
        print("after")
        return result

    def get(self,request):
        print(request.method)
        return render(request,'home.html')

    def post(self,request):
        print(request.method,'POST')
        return render(request,'home.html')
View Code

 

   其实使用FBV还是CBV,其实看个人习惯,能实现需求就行,建议两种都使用。 

 

路由器系统(url):

  Django模板语言循环字典:

html写法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    {{ user_dict.k1}}
    <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>
#在取字典的值得时候,我们有三种取发,取key、values和全部。
View Code

django写法:

USER_DICT = {
    'k1':'root1',
    'k2':'root2',
    'k3':'root3',
    'k4':'root4',
}
def index(request):
    return  render(request,'index.html',{'user_dict':USER_DICT})
View Code

 

  1、单一路由:

url(r'^index$', views.index),       url(r'^home/', views.Home.as_view()),

  views里面定义函数的时候除了设置request形参,还需要设置设置一个形参,如果形参过多的话,容易获取的参数顺序不对

url(r'^detail-(\d+).html', views.detail),  

  

  建议使用以下这种路由,这样的话,下面函数里面的nid和nid哪个在前哪个在后就没有关系了

url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail)
def func(request,nid,uid):
    pass

 

扩展:如果使用万能参数的话,除了request参数,后面有多少个参数都行,一个参数的话就是元祖,多个的话就是字典模式。

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

 

 

路由分发:

  

django下的urls.py

from  django.conf.urls import url,include

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

app01下的urls.py(需要自己建)

from  django.conf.urls import  url,include
from app01 import views

urlpatterns = [
    url(r'^login/', views.login),
    url(r'^orm/', views.orm),
]

app02下的urls.py(需要自己建)

from  django.conf.urls import  url,include
from app02 import views

urlpatterns = [
    url(r'^moniter/', views.login),
]

 

这样的话,写不同app功能的人,就不会把url搞混淆了。

 Django的ORM操作:

  创建数据库表结构:

  一:

    使用python创建项目时候自带的db.sqlite3

    1、前面我们说过,创建了app以后有个叫modles.py的文件,当时说在这里创建数据的,现在我们用到了它。

在需要生成数据库表结构的app里面的models里面创建表结构(创建类,并继承modes类)。   

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)

    2、注册app(因为我们在一个项目里面肯定会有很多的功能,也就是有很多的app。这样的话,每个app里面都有models文件,django也不知道你要在哪个app里面创建表结构,所以我们需要先注册app)

 在项目里面的settings.py里面找到如下内容,在最后添加你要创建到哪个app的名称。例如:

INSTALLED_APPS = [
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages',
            'django.contrib.staticfiles',
            'app01',
        ]
例如我要在app01里面创建表结构

    注意:djang3.2版本的注册方式还需要更改一下数据库连接参数DATABASES

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        # 'NAME': BASE_DIR / 'db.sqlite3',
        'NAME': str(BASE_DIR.joinpath("db.sqlite3")),
    }
}

  

    3、然后我们需要执行两个命令,

      python manage.py  makemigrations(执行完这个命令,在你想创建表结构的app里面的migrations里面就会多出一个东西来,这个就是表结构发生变化后,自动给你生成的文件,类似于日志)

      python manage.py  migrate  (把上面那条命令的内容直接在数据库里面执行,也就是真正意义上的在数据库里面生成表结构)

  二:

    使用mysql数据库:

    1、上面写的使用db.sqlites的1和2步骤执行一遍,然后执行下面的操作。

    2、因为python3里面没有MySqldb这模块,而django默认使用的是它,因为python3里面我们用的pymsql,所以我们要在project同名下的__init__.py文件里面加上以下内容。

    

import pymysql
pymysql.install_as_MySQLdb()

 

    3、找到项目里面有个settings.py文件,里面有个DATEBASES的字典。

把defalut默认使用sqlite3的这个全部都注释。

DATABASES = {

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

 

添加下面这些内容,注意,里面NAME是数据库名称,这个必须提前在数据库里面手动生成。

DATABASES = {

    # 'default': {
    #     'ENGINE': 'django.db.backends.sqlite3',
    #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    # }
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'cmdb',
    'USER': 'root',
    'PASSWORD': '12345678',
    'HOST': '192.168.16.200',
    'PORT': '3306',
    }
}

    4、在mysql数据库里面生成数据库表结构。

      python manage.py  makemigrations(执行完这个命令,在你想创建表结构的app里面的migrations里面就会多出一个东西来,这个就是表结构发生变化后,自动给你生成的文件,类似于日志)

      python manage.py  migrate  (把上面那条命令的内容直接在数据库里面执行,也就是真正意义上的在数据库里面生成表结构)

 

 

扩展:

  连接sqlite3方法:

    首先需要下载navicat premium。安装好后,如下:

              

     复制sqlite路径

              

     将project名称完完全全的复制到连接名里面,并将上面复制的sqlite路径粘贴到数据库文件里,就OK了。

              

 示例:

  我们搞一个登陆验证的示例,使用的是sqlite3数据库。

  1、创建数据方法一。

  上面我们在models.py里面已经写好了数据库表结构,并已经生成了表结构。

#首先导入数据库表结构的目录
from
app01 import models
#例如有个orm的字段请求,我让它发送一个请求,就帮我创建一个用户名和密码(root,123),并返回orm
def orm(request):
#下面这条才是关键,使用models.什么就是生成数据库表结构的类名,后面都是关键字,username和password都是字段名称 models.UserInfo.objects.create(username
= "root",password = '123') return HttpResponse("orm")

  

  创建数据方法二。

obj = models.UserInfo(username='zhangsan',password='123')
obj.save

 

  2、查询

result = models.UserInfo.objects.all()
for row in result:
    print(row.id,row.username,row.password)
#上面这种就会取出所有的username和password的数据。

result = models.UserInfo.objects.filter(username='root',password='123')
#上面这种是过滤条件,逗号充当的是and的意思

 

  3、删除

models.UserInfo.objects.all().delete()
#删除所有数据

#删除root用户
models.UserInfo.objects.filter(username='root').delete()

 

  4、更新

#将password字段全部都改成666
models.UserInfo.objects.all().uodate(password='666')

#根据过滤更新(让id等于3的这条数据的password改成666)
models.UserInfo.objects.filter(id=3).uodate(password='666')

 

posted @ 2016-12-14 10:44  Charles.L  阅读(475)  评论(0编辑  收藏  举报