Django 框架 第二章

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

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

## 注意事项:html

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

 

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

静态文件能够是mysql

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

图片正则表达式

csssql

js数据库

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

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()  # 后缀和参数所有获取

相关文章
相关标签/搜索