Django 框架 第二章

1,Django  框架中新建的app应用,一定先去settings.py注册

        INSTALLED_APPS = [
                'django.contrib.admin',
                'django.contrib.auth',
                'django.contrib.contenttypes',
                'django.contrib.sessions',
                'django.contrib.messages',
                'django.contrib.staticfiles',
                # 'app01'  # 简写
                'app01.apps.App01Config'  # 全称
            ]

## 注意事项:

2, html文件默认全都放在templates文件夹下

 

对于前段已经写好了的文件 我们只是拿过来使用 那么这些文件都可以称之为叫"静态文件"

静态文件可以是

bootstrap一类的前段框架 已经写好了的

图片

css

js

静态文件默认全都放在static文件夹下

static文件夹中默认会默认创建的子文件夹

css文件夹  当前网站所有的样式文件

js文件  当前网站所有的js文件

img文件  当前网站所有的图片文件

其他(前端框架代码 第三方插件代码...)

 

 

启动ddjango项目的时候 一定要确保一个端口号只有一个django项目在占用

不然的话 会容易造成bug、

 

用户可以访问的资源 都在url中

只有url中开设相关的资源你才能访问到(******)

后端资源一般都需要手动指定是否需要暴露给用户

 

## 3 静态文件配置

 

STATICFILES_DIRS = [
            os.path.join(BASE_DIR,'static')
    ]
    ##你只要输入static文件夹内具体文件的路径就能够访问到

 

 # 

STATIC_URL = '/static/'  # 这个static不是文件夹的名字 而是接口前缀

 """只要你想访问静态文件中的资源 文件路径就必须用static开头"""

 # 手动将static文件夹中所有的资源暴露给用户

 STATICFILES_DIRS = [

  os.path.join(BASE_DIR,'static'),  # 真正的文件夹路径

  os.path.join(BASE_DIR,'static1'),  # 真正的文件夹路径

  os.path.join(BASE_DIR,'static2'),  # 真正的文件夹路径

  os.path.join(BASE_DIR,'static3')  # 真正的文件夹路径

 ]

 

 

 

##

django默认是支持自动重启代码的 所以你只需要多刷新几次页面就可以

但是有时候它的重启机制比较慢

机制:实时监测文件代码变化 只要有变化 就会自动重启 

可能你的代码还没有写完 这个时候就会自动报错

 

##

静态文件接口前缀"动态解析"

##静态文件接口前缀"动态解析"
        {% load static %}

        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
##    利用解析器 动态获取接口前缀 

##

重点!

form表单默认是get请求

携带数据的方式是url问好后跟数据

http://127.0.0.1:8000/login/?username=zekai&password=123

 

  

可以通过method改为post请求

改成post请求之后 需要去settings文件中注释掉一个中间件

MIDDLEWARE = [
            'django.middleware.security.SecurityMiddleware',
            'django.contrib.sessions.middleware.SessionMiddleware',
            'django.middleware.common.CommonMiddleware',
            # 'django.middleware.csrf.CsrfViewMiddleware', ## 注释中间件
            'django.contrib.auth.middleware.AuthenticationMiddleware',
            'django.contrib.messages.middleware.MessageMiddleware',
            'django.middleware.clickjacking.XFrameOptionsMiddleware',
        ]

##

form 表单提交数据的由 action 的三种方法:

1.不写的情况下 默认往当前地址提交

2.还可以写后缀/index/(将项目常用这种)

 

3.还可以写全路径

 

 

##

 

Django的路由系统

 

 

参数说明:

  • 正则表达式:一个正则表达式字符串
  • views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
  • 参数:可选的要传递给视图函数的默认参数(字典形式)
  • 别名:一个可选的name参数

正则表达式详解

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

# 注意事项

  1. urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
  2. 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
  3. 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
  4. 每个正则表达式前面的'r' 是可选的但是建议加上。
# 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
APPEND_SLASH=True

Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其作用就是自动在网址结尾加'/'。

其效果就是:

我们定义了urls.py:

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

urlpatterns = [
        url(r'^blog/$', views.blog),
]

访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/ 。

如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时就会提示找不到页面。

##  

视图函数一般主要会先处理get请求

        def login(request):
            # 视图函数针对不同的请求方式 应该有不同的处理逻辑
            # if request.method == 'GET':
            #     print('收到了')
            #     print(request.method)  # 能够获取前端请求方式 并且是全大写的字符串
            #     print(type(request.method))
            #     return render(request,'login.html')
            # elif request.method == 'POST':
            #     # 获取用户输入 做相应的逻辑判断
            #     return HttpResponse("拿到了 老弟")
            if request.method == 'POST':
                return HttpResponse('来啦 宝贝')
            return render(request,'login.html')

# 获取前端数据

在后端PY 文件中 request.method获取请求方式: get,  post

对数据的处理 不单单只有wsgiref模块  django后端也进行了大量的数据处理

GET

 

request.GET获取前端get提交的数据(就类似于是一个大字典)

取值

request.GET.get('username')  # 虽然value是一个列表 但是默认只取列表最后一个元素

# 强烈不建议你使用中括号的形式取值

 

# 如果想直接把列表全部取出(******)

request.GET.getlist('hobby')

POST

request.POST获取前端post提交的数据(就类似于是一个大字典)

取值

request.POST.get('username')  # 虽然value是一个列表 但是默认只取列表最后一个元素

# 强烈不建议你使用中括号的形式取值

 

# 如果想直接把列表全部取出(******)

request.POST.getlist('hobby')

 

 

## 数据库配置

 

django默认使用的是自带的sqlite数据库  

如果你想让它其他的数据库  需要在settings配置文件中 配置

 

# 1.settings文件中配置
                DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'day51',
                'HOST':'127.0.0.1',
                'PORT':3306,
                'USER':'root',
                'PASSWORD':'123',
                'CHARSET':'utf8'
            }
}
# 2.还要在项目名下的init文件或者是应用名下的init文件中告诉django不要使# 用默认的mysqldb连接mysql
        # 而是使用pymysql
            import pymysql
            pymysql.install_as_MySQLdb()

## 

django orm

ORM 对象关系映射

表    ----- -----      类

一条条记录 -----   对象

字段对应的值   ---  对象的属性

1,模型表的建立过程:

首先需要在应用下的models.py中书写模型类

 

class User(models.Model):
            # 将id字段设置为User表主键字段  在django orm中 你可以不写主键字典  django会默认给你的表创建一个名为id的主键字段
            # id = models.AutoField(primary_key=True)  # 一旦你自己指定了主键字段 那么django就不会自动再帮你创建了
            username = models.CharField(max_length=32)  # username varchar(32)   CharField必须要指定max_length参数
            password = models.IntegerField()  # password int
    *************************需要执行数据库迁移(同步)命令******************************
    python3 manage.py makemigrations  # 仅仅是在小本本上(migrations文件夹)记录数据库的修改 并不会直接操作数据
    python3 manage.py migrate  # 将数据库修改记录 真正同步到数据库

注意:只要动了models中跟数据库相关的代码 就必须重新执行上面的两条命令 缺一不可!!!!

###

 

2,表字段的增删改查

 

 

当一张表已经创建出来之后 后续还想添加字段,可以有两种方式

1.给新增的字段设置默认值

addr = models.CharField(max_length=32,default='China')  # default该字段默认值

 

2.给新增的字段设置成可以为空

age = models.IntegerField(null=True)  # 该字段允许为空

2,删除

删(慎用)

删除字段 直接在models.py中注释该字段 然后重新执行两条命令即可

python3 manage.py makemigrations  # 仅仅是在小本本上(migrations文件夹)记录数据库的修改 并不会直接操作数据
    python3 manage.py migrate  # 将数据库修改记录 真正同步到数据库

注意:执行完之后 表中该字段所对应的所有的数据全部删除

并且一般情况下 基本是不会用到真正意义上的删除

 

3,

orm操作需要使用models中的类的名字

##数据的查
        from app01 import models
        
        models.User.objects.all()  # 直接拿所有的数据
        
        models.User.objects.get(username=username)  
        
        res = models.User.objects.filter(username=username)
        res.query 
        
##数据的增
        1.
        models.User.objects.create(username=username,password=password)
        2.
        user_obj = models.User(username=username,password=password)
        user_obj.save()
    
#
        models.User.objects.filter(条件).delete()
    
#
        models.User.objects.filter(条件).update()
        

 

路由层

url()方法 第一个参数 其实是一个正则表达式

 

路由匹配 

 

url(正则表达式,视图函数内存地址)

 

只要正则匹配到了内容,就不再继续往下匹配,而是直接后面的视图函数

 

匹配首页

 

url(r'^$',home)

 

匹配尾页

 

url(r'',errors)

 

## 路由匹配的规律

 

第一次按照用户输入什么就匹配什么如果匹配不上

 

第二次django会让浏览器自动再尾部加斜杠再次匹配 还匹配不上就会报错

 

上述规律不是浏览器的特点,是django的功能

 

django settings文件中

APPEND_SALSH = True  # 自动加斜杠

 

"""为什么setting文件中变量名必须写全大写"""

 

一旦前面的正则匹配到了内容 就不会再往下继续匹配 而是直接执行对应的视图函数

 

正是由于上面的特性  当你的项目特别庞大的时候  url的前后顺序也是你需要你考虑

 

极有可能会出现url错乱的情况

 

 

django在路由的匹配的时候  当你在浏览器中没有敲最后的斜杠

django会先拿着你没有敲斜杠的结果取匹配 如果都没有匹配上  会让浏览器在末尾加斜杠再发一次请求 再匹配一次 如果还匹配不上才会报错

如果你想取消该机制 不想做二次匹配可以在settings配置文件中 指定

APPEND_SLASH = False  # 该参数默认是True

 

 

无名分组

url(r'^test/([0-9]{4})/', views.test)

路由匹配的时候 会将括号内正则表达式匹配到的内容 当做位置参数传递给视图函数

test(request,2019)

 

有名分组

url(r'^test/(?P<year>\d+)/', views.test)

路由匹配的时候 会将括号内正则表达式匹配到的内容 当做关键字参数传递给视图函数

test(request,year=2019)

 

# 无名有名不能混合使用 !!!

    url(r'^test/(\d+)/(?P<year>\d+)/', views.test),

 

但是用一种分组下 可以使用多个

# 无名分组支持多个

# url(r'^test/(\d+)/(\d+)/', views.test),

# 有名分组支持多个

# url(r'^test/(?P<year>\d+)/(?P<xx>\d+)/', views.test),

 

 

反向解析

本质:其实就是给你返回一个能够返回对应url的地址

 

1.先给url和视图函数对应关系起别名

url(r'^index/$',views.index,name='kkk')

 

2.反向解析

后端反向解析

后端可以在任意位置通过reverse反向解析出对应的url

from django.shortcuts import render,HttpResponse,redirect,reverse

reverse('kkk')

 

前端反向解析

{% url 'kkk' %}

 

无名分组反向解析

 

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

 

后端反向解析

reverse('kkk',args=(1,))  # 后面的数字通常都是数据的id值

前端反向解析

{% url 'kkk' 1%}   # 后面的数字通常都是数据的id值

 

 

有名分组反向解析

同无名分组反向解析意义的用法

 

url(r'^index/(?P<year>\d+)/$',views.index,name='kkk')

 

后端方向解析

print(reverse('kkk',args=(1,)))  # 推荐你使用上面这种

print(reverse('kkk',kwargs={'year':1}))

前端反向解析

<a href="{% url 'kkk' 1 %}">1</a>  # 推荐你使用上面这种

<a href="{% url 'kkk' year=1 %}">1</a>

 

例子:

 

 传参数

 

 

 

注意:在同一个应用下 别名千万不能重复!!!

 

 

路由分发(******)

当你的django项目特别庞大的时候 路由与视图函数对应关系特别特别多 

那么你的总路由urls.py代码太过冗长  不易维护

 

每一个应用都可以有自己的urls.py,static文件夹,templates文件夹(******)

 

正是基于上述条件 可以实现多人分组开发 等多人开发完成之后  我们只需要创建一个空的django项目

然后将多人开发的app全部注册进来 在总路由实现一个路由分发 而不再做路由匹配(来了之后 我只给你分发到对应的app中)

 

 

当你的应用下的视图函数特别特别多的时候  你可以建一个views文件夹 里面根据功能的细分再建不同的py文件

 

 

 urlpatterns = [

   url(r'^admin/', admin.site.urls),

   url(r'^app01/',include('app01.urls')),

   url(r'^app02/',include('app02.urls')),

 

  ]

 

 

 

 

 

名称空间(了解)

多个app起了相同的别名 这个时候用反向解析 并不会自动识别应用前缀

如果想避免这种问题的发生

方式1:

 

总路由

url(r'^app01/',include('app01.urls',namespace='app01'))

url(r'^app02/',include('app02.urls',namespace='app02'))

 

后端解析的时候

reverse('app01:index')

reverse('app02:index')

前端解析的时候

{% url 'app01:index' %}

{% url 'app02:index' %}

 

方式2:

起别名的时候不要冲突即可  一般情况下在起别名的时候通常建议以应用名作为前缀

name = 'app01_index'

name = 'app02_index'

 

 

 

伪静态

静态网页:数据是写死的 万年不变

 

伪静态网页的设计是为了增加百度等搜索引擎seo查询力度

 

所有的搜索引擎其实都是一个巨大的爬虫程序

 

网站优化相关  通过伪静态确实可以提高你的网站被查询出来的概率

但是再怎么优化也抵不过RMB玩家

 

 

 

虚拟环境

 

一般情况下 我们会给每一个项目 配备该项目所需要的模块 不需要的一概不装

虚拟环境 就类似于为每个项目量身定做的解释器环境

 

 

如何创建虚拟环境

每创建一个虚拟环境 就类似于你又下载了一个全新的python解释器

 

 

django版本的区别

django1.X跟django2.X版本区别

路由层1.X用的是url

而2.X用的是path

 

2.X中的path第一个参数不再是正则表达式,而是写什么就匹配什么 是精准匹配

 

当你使用2.X不习惯的时候  2.X还有一个叫re_path

2.x中的re_path就是你1.X的url

 

 

虽然2.X中path不支持正则表达式  但是它提供了五种默认的转换器

 

1.0版本的url和2.0版本的re_path分组出来的数据都是字符串类型

默认有五个转换器,感兴趣的自己可以课下去试一下

str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式

int,匹配正整数,包含0。

slug,匹配字母、数字以及横杠、下划线组成的字符串。

uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。

path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)

 

 

 

path('index/<int:id>/',index)  # 会将id匹配到的内容自动转换成整型

 

 

 

还支持自定义转换器

class FourDigitYearConverter:  

regex = '[0-9]{4}'  

def to_python(self, value):  

return int(value)  

def to_url(self, value):  

return '%04d' % value  占四位,不够用0填满,超了则就按超了的位数来!

register_converter(FourDigitYearConverter, 'yyyy')  

 

urlpatterns = [  

path('articles/2003/', views.special_case_2003),  

path('articles/<yyyy:year>/', views.year_archive),  

...  

]  

 

 

视图层

1.小白必会三板斧

1.HttpResponse

2.render

3.redirect

django视图函数必须要给返回一个HttpResponse对象

 

前后端分离

前端一个人干(前端转成自定义对象)

JSON.stringify()        json.dumps()

JSON.parse() json.loads()

 

 

后端另一个干(python后端用字典)

只要涉及到数据交互,一般情况下都是用的json格式

后端只负责产生接口,前端调用该接口能拿到一个大字典

后端只需要写一个接口文档 里面描述字典的详细信息以及参数的传递

2.JsonReponse

from django.http import JsonResponse

def index(request):

data = {'name':'jason好帅哦 我好喜欢','password':123}

l = [1,2,3,4,5,6,7,8]

# res = json.dumps(data,ensure_ascii=False)

# return HttpResponse(res)

# return JsonResponse(data,json_dumps_params={'ensure_ascii':False})

return JsonResponse(l,safe=False)  # 如果返回的不是字典 只需要修改safe参数为false即可

 

3.上传文件

form表单上传文件需要注意的事项

1.enctype需要由默认的urlencoded变成formdata

2.method需要由默认的get变成post

(目前还需要考虑的是 提交post请求需要将配置文件中的csrf中间件注释)

   

  form表单上传文件

需要注意的实现

1.method必须是post

2.enctype必须要指定成formdata

3.目前需要考虑的 需要将settings配置文件中的csrf中间件注释掉

后端不再通过request.POST获取文件数据,而是通过request.FILES

file_obj = request.FILES.get('myfile')

file_obj.name  # 文件名

with open(file_obj.name,'wb') as f:

for chunk in file_obj.chunks():

f.write(chunk)

 

如果form表单上传文件 后端需要在request.FILES获取文件数据 而不再是POST里面

 

 

request.method

request.GET

request.POST

request.FILES

request.path  # 只回去url后缀 不获取?后面的参数

request.get_full_path()  # 后缀和参数全部获取

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-09-19 18:59  Drew-c  阅读(140)  评论(0编辑  收藏  举报