django基础

50 篇文章 4 订阅

mkvirtualenv django_py3_1.11 -p python3 pip install django==1.11.11

创建项目 django-admin startproject 工程名称 settings.py 是项目的整体配置文件。 INSTALLED_APPS项保存了工程中已经注册安装的子应用’users.apps.UsersConfig’ ->(flask 注册蓝图) urls.py 是项目的URL配置文件。 wsgi.py 是项目与WSGI兼容的Web服务器入口。 manage.py 是项目管理文件,通过它管理项目

python manage.py runserver ip:端口 默认IP是127.0.0.1,默认端口为8000。 (与工程同名的应用文件夹,是项目的<主应用>, 用于注册管理子应用的,设置,数据库初始化)

创建子应用 python manage.py startapp 子应用名称 admin.py 文件跟网站的后台管理站点配置相关。 apps.py 文件用于配置当前子应用的相关信息。 migrations 目录用于存放数据库迁移历史文件。 models.py 文件用户保存数据库模型类。 tests.py 文件用于开发测试用例,编写单元测试。 views.py 文件用于编写Web应用视图。

views.py定义视图函数 def fun(request) request必要参数->Django 构造的 http请求对象 return HttpResponse() HttpResponse必要函数->Django 构造的 http响应对象

子应用/urls.py 保存应用路由 ->(FLask route装饰器) from django.conf.urls import url from . import views # urlpatterns是被django自动识别的路由列表变量 urlpatterns = [ # 每个路由信息都需要使用url函数来构造 # url(路径, 视图) url(r’^index/$’, views.index), ]

项目/urls.py 总路由中添加子应用路由数据 -> (flask 创建注册蓝图并设置url_prefix 给路由添加url前缀) urlpatterns = [ url(r’^admin/’, admin.site.urls), # django默认包含的 # 添加 url(r’^users/’, include(‘users.urls’)), ]

配置文件 settings.py 1. BASE_DIR BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file))) 当前工程的根目录,Django会依此来定位工程内的相关文件,我们也可以使用该参数来构造文件路径。 2. DEBUG DEBUG = True ALLOWED_HOSTS = [] # DEBUG = False # ALLOWED_HOSTS = [’*’]

  1. 本地语言与时区
    LANGUAGE_CODE = ‘en-us’ # 语言
    TIME_ZONE = ‘UTC’ # 时区
    LANGUAGE_CODE = ‘zh-hans’
    TIME_ZONE = ‘Asia/Shanghai’
    静态文件 ->(return current_app.send_static_file(‘news/favicon.ico’)) STATICFILES_DIRS 存放查找静态文件的目录 STATIC_URL 访问静态文件的URL前缀 # only use in development STATIC_URL(flask static_url_path) = ‘/static/’
    #127.0.0.1/static/filename

STATICFILES_DIRS(flask static_folder="static) =
[os.path.join(BASE_DIR, “static_files”)]
# set static dir path, join ->获取当前目录,并组合成新目录.
# BASE_DIR是项目根目录, 我们在根目录下创建 "static_files"文件夹

!!!注意!!!
Django 仅在调试模式下(DEBUG=True)能对外提供静态文件。
当DEBUG=False工作在生产模式时,Django不再对外提供静态文件,需要是用collectstatic命令来收集静态文件并交由其他静态文件服务器来提供。(详细在部署时会讲)
路由命名 :避免不同应用中的路由使用了相同的名字发生冲突,使用命名空间区别开。

在使用include函数定义路由时,可以使用namespace参数定义路由的命名空间,如
url(r’^users/’, include(‘users.urls’, namespace=‘users’)),
凡是users.urls中定义的路由,均属于namespace指明的users名下

在定义普通路由时,可以使用name参数指明路由的名字,如
urlpatterns = [
url(r’^index/$’, views.index, name=‘index’),
url(r’^say’, views.say, name=‘say’),
]

Q&A
关于路由命名
在总路由中使用include包含了子应用的路由, 那么用户访问的URL是 users/XXXX, 就算在不同的应用中使用了相同的名字, 也会因用于的访问URL prefix前缀不同而区分. 为什么还要再去特别做命名的动作?
reverse反解析 :根据路由名称,返回具体的路径 url = reverse(‘users:index’) # 返回 /users/index/ 对于未指明namespace的,reverse(路由name) 对于指明namespace的,reverse(命名空间namespace:路由name) 上述例子属于第二种 Q&A 对于未指明namespace的,reverse(路由name), 是否只能解析找到到当前模块(views)下的路由?

路径结尾斜线/的说明 urlpatterns = [ url(r’^index/$’, views.index, name=‘index’), ] 用户访问 index 或者 index/ 网址,均能访问到index视图. Django会把用户重定向到以斜线/结尾的路径上,而不会返回404不存在

!!!说明:!!!
虽然路由结尾带/能带来上述好处,但是却违背了HTTP中URL表示资源位置路径的设计理念。
是否结尾带/以所属公司定义风格为准。
App应用配置 子应用下apps.py文件(注册到settings/INSTALLED_APPS) AppConfig.name : 加载到哪个应用的,每个配置类必须包含此属性,默认自动生成。 AppConfig.verbose_name : 该应用的直观可读的名字,此名字在Django提供的Admin管理站点中会显示

请求 1. 提取URL的特定部分,如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取; url(r’^weather/([a-z]+)/(\d{4})/KaTeX parse error: Expected 'EOF', got '\d' at position 65: …-z]+)/(?P<year>\̲d̲{4})/’, views.weather) 命名参数 #在路由时,用()包裹动态内容 def get_weather(request,city,year): args = request.GET city=args.get(‘city’) year=args.get(‘year’)

  1. 查询字符串(query string),形如get_string/?key1=value1&key2=value2&key1=value3;
    def get_string(request):
    args = request.GET
    key1=args.get(‘key1’)
    key2=args.get(‘key2’)
    key1_list=args.getlist(‘key1’)

  2. 请求体(body)中发送的数据,比如表单数据、json、xml;
    Form Data表单
    form=request.POST
    print(form.get(‘a’))
    print(form.get(‘b’))
    print(form.getlist(‘a’))

    Non-Form Data(ajax)
    body=request.body #body是bytes类型

    把body转化为转化为字符串

    body_str=body.decode()

    构建json数据

    json_data=json.loads(body_str)
    print(json_data)
    print(json_data.get(‘a’))
    print(json_data.get(‘b’))

    !!!
    Django默认开启了CSRF防护,会对上述请求方式进行CSRF防护验证,在测试时可以关闭CSRF防护机制,方法为在settings.py文件中注释掉CSRF中间件

  3. 在http报文的头(header)中。

    读取header字典

    headers=request.META ->(request.header )
    print(headers.get(‘CONTENT_TYPE’))
    CONTENT_LENGTH – The length of the request body (as a string).
    CONTENT_TYPE – The MIME type of the request body.
    HTTP_ACCEPT – Acceptable content types for the response.
    HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.
    HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.
    HTTP_HOST – The HTTP Host header sent by the client.
    HTTP_REFERER – The referring page, if any.
    HTTP_USER_AGENT – The client’s user-agent string.
    QUERY_STRING – The query string, as a single (unparsed) string.
    REMOTE_ADDR – The IP address of the client.
    REMOTE_HOST – The hostname of the client.
    REMOTE_USER – The user authenticated by the Web server, if any.
    REQUEST_METHOD – A string such as “GET” or “POST”.
    SERVER_NAME – The hostname of the server.
    SERVER_PORT – The port of the server (as a string).

  4. 其他常用HttpRequest对象属性
    method :一个字符串,表示请求使用的HTTP方法,常用值包括:‘GET’、‘POST’。
    user :请求的用户对象。
    path :一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
    FILES :一个类似于字典的对象,包含所有的上传文件。
    encoding:一个字符串,表示提交的数据的编码方式。
    如果为None则表示使用浏览器的默认设置,一般为utf-8。
    这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
    响应 HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码) 响应头可以直接将HttpResponse对象当做字典进行响应头键值对的设置: response = HttpResponse() response[‘Itcast’] = ‘Python’ # 自定义响应头Itcast, 值为Python

HttpResponseRedirect 301
HttpResponsePermanentRedirect 302
HttpResponseNotModified 304
HttpResponseBadRequest 400
HttpResponseNotFound 404
HttpResponseForbidden 403
HttpResponseNotAllowed 405
HttpResponseGone 410
HttpResponseServerError 500

return重定向
return redirect(‘url’或’/index.html’)# 如果是/开头 ,则是绝对路径. 重定向找的是路径

return JsonResponse()
#如果return的是list,safe=false

Cookie
HttpResponse.set_cookie(cookie名, value=cookie值, max_age=cookie有效期)
cookie1 = request.COOKIES.get(‘itcast1’)

Session
pip install django-redis
配置/settings.py
CACHES = {
“default”: {
#使用缓存引擎
“BACKEND”: “django_redis.cache.RedisCache”,
#连接redis
“LOCATION”: “redis://127.0.0.1:6379/1”,
“OPTIONS”: {
“CLIENT_CLASS”: “django_redis.client.DefaultClient”,
}
}
}
#Django session 使用的储存方式
SESSION_ENGINE = “django.contrib.sessions.backends.cache”
#使用哪一个缓存
SESSION_CACHE_ALIAS = “default”

request.session[‘键’]=值
request.session.get(‘键’,默认值)
request.session.clear()
request.session.flush()
del request.session[‘键’]
request.session.set_expiry(value)
如果value为None,那么session有效期将采用系统默认值,默认为两周,可以通过在settings.py中设置SESSION_COOKIE_AGE来设置全局默认值
类视图 viewspy from django.views.generic import View

class RegisterView(View):
“”“类视图:处理注册”""

def get(self, request):
    """处理GET请求,返回注册页面"""
    return render(request, 'register.html')

def post(self, request):
    """处理POST请求,实现注册逻辑"""
    return HttpResponse('这里实现注册逻辑')

urls.py
urlpatterns = [
#视图函数:注册
#url(r’^register/ ′ , v i e w s . 视 图 函 数 名 , n a m e = ′ r e g i s t e r ′ ) , 类 视 图 : 注 册 u r l ( r ′ r e g i s t e r / &#x27;, views.视图函数名, name=&#x27;register&#x27;), 类视图:注册 url(r&#x27;^register/ ,views.,name=register),url(rregister/’, views.类视图名.as_view(), name=‘register’),
]

类视图使用装饰器 urls.py urlpatterns = [ #装饰类下所有方法(装饰器内层无Self参数) url(r’^register/$’, 装饰器名(views.类视图名.as_view())) ] #装饰类视图下某一个方法 方法1 #方法上 @method_decorator(装饰器名) def get(self, request): print(‘get方法’) return HttpResponse(‘ok’) 方法2 #类上 @method_decorator(装饰器名,name=“方法名”) class register(view) 方法3 #类上,所有方法 @method_decorator(装饰器名,name=“dispatch”) class register(view) 方法4 #扩展类实现装饰 class MyDecoratorMixin(object): #扩展类 @classmethod def as_view(cls, *args, **kwargs): view = super().as_view(*args, **kwargs) #super根据MRO顺序, 继承下一个参数view的as_view方法. view = my_decorator(view) #对view进行装饰 return view

class DemoView(MyDecoratorMixin, View):
def get(self, request):
print(‘get方法’)
return HttpResponse(‘ok’)
中间件 根目录/middleware.py(定义在哪都是全局) def simple_middleware(get_response): # 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。 def middleware(request): # 此处编写的代码会在每个请求处理视图前被调用。 # 请求中间件从上向下顺序 response = get_response(request) # 响应中间件从下向上顺序 # 此处编写的代码会在每个请求处理视图之后被调用。 return response return middleware

定义好中间件后,需要在settings.py 文件中MIDDLEWARE添加注册中间件
‘(子应用模块名.)py文件名.(中间件名)’, # 添加中间件
数据库ORM (pip install mycli mysql自动提示工具,mycli -uroot -p) pip install PyMySQL 项目/主应用/init.py from pymysql import install_as_MySQLdb install_as_MySQLdb()

settings.py
DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.mysql’,
‘HOST’: ‘127.0.0.1’, # 数据库主机
‘PORT’: 3306, # 数据库端口
‘USER’: ‘root’, # 数据库用户名
‘PASSWORD’: ‘mysql’, # 数据库用户密码
‘NAME’: ‘django_demo’ # 数据库名字
}
}
定义 子引用/models.py from django.db import models

#定义图书模型类BookInfo
class BookInfo(models.Model):
btitle = models.CharField(max_length=20, verbose_name=‘名称’)
bpub_date = models.DateField(verbose_name=‘发布日期’)
bread = models.IntegerField(default=0, verbose_name=‘阅读量’)
bcomment = models.IntegerField(default=0, verbose_name=‘评论量’)
is_delete = models.BooleanField(default=False, verbose_name=‘逻辑删除’)

class Meta:
    db_table = 'tb_books'  # 指明数据库表名
    verbose_name = '图书'  # 在admin站点中显示的名称
    <del> verbose_name_plural = verbose_name </del> # 显示的复数名称 

def __str__(self):
    """定义每个数据对象的显示信息"""
    return self.btitle

!!!看课件!!!
迁移 生成迁移文件 python manage.py makemigrations (makemigration为初始化携带,不能删除文件夹) 同步到数据库中 python manage.py migrate shell工具 Django的manage工具提供了shell命令,帮助我们配置好当前工程的运行环境(如连接好数据库等),以便可以直接在终端中执行测试python语句 python manage.py shell 导入两个模型类,以便后续使用. pip install ipython ->安装自动补全. 进入shell 需要在执行 from booktest.models import BookInfo, HeroInfo 导入数据

!!!增删改查 看课件!!!

模板使用 settings.py TEMPLATES = [ ‘DIRS’: [os.path.join(BASE_DIR, ‘templates’)], # 此处修改

模板渲染 def index(request): context={‘city’: ‘北京’} return render(request,‘index.html’,context

模板语句 运算符 {% if a == 1 %} # 正确 {% if a==1 %} # 错误

QuerySet 1. 支持链式调用 2. exists() 判断查询集中是否有数据,如果有则返回True,没有则返回False。 3. 限制查询集 对查询集进行切片后返回一个新的查询集,不会立即执行查询 特性 惰性执行 缓存

数据库操作—增、删、改、查 <增加> 通过类创建实例对象 book=Bookinfo(实例属性). 需要提交 book.save()

<查询> get() 查询单一结果,如果不存在会抛出模型类.DoesNotExist异常。 book = BookInfo.objects.get(btitle=‘西游记’) -> 表类名.objects.get(属性(列)=“search”) -> 实例对象 book.属性 调用 注意!get方法如果取到多个数据,则会报错如下. 所以一般使用get->pk get() returned more than one BookInfo – it returned 2!

all() 查询多个结果。
BookInfo.objects.all() -> 表类名.pobjects.all() -> Queryset

count() 查询结果数量
<过滤查询> 属性名称__比较运算符 = 值 filter() 过滤出多个结果 exclude() 排除掉符合条件剩下的结果 get() 过滤单一结果

exact:相等
BookInfo.objects.filter(id__exact=1)
BookInfo.objects.filter(id=1)

contains:是否包含 / startswith、endswith:以指定值开头或结尾
BookInfo.objects.filter(btitle__contains=‘search’)

isnull:是否为null
BookInfo.objects.filter(btitle__isnull=False)

in:是否包含在范围内
BookInfo.objects.filter(id__in=[1, 3, 5])

比较查询
gt 大于 (greater then)
gte 大于等于 (greater then equal)
lt 小于 (less then)
lte 小于等于 (less then equal)

year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。
BookInfo.objects.filter(bpub_date__year=1980)
BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1))
<F对象> 属性与属性的比较-> Queryset. from django.db.models import F BookInfo.objects.filter(bread__gte=F(‘bcomment’)) -> F(属性名) F对象可使用算数运算 BookInfo.objects.filter(bread__gt=F(‘bcomment’) * 2)

<Q对象> 多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字 from django.db.models import Q &表示逻辑与 ,|表示逻辑或 Q(属性名__运算符=值) BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))

~表示逻辑非 -> !
BookInfo.objects.filter(~Q(pk=3))
<聚合函数> aggregate()过滤器调用聚合函数 -> “dict”. from django.db.models import Sum in:BookInfo.objects.aggregate(Sum(‘bread’)) out:{‘bread__sum’:3}

<排序> BookInfo.objects.all().order_by(‘bread’) # 升序 BookInfo.objects.all().order_by(’-bread’) # 降序

<关联查询> 由一到多的访问语法: "一"的实例对象. "多"的模型类名小写_set b = BookInfo.objects.get(id=1) -> 得到实例对象 b.heroinfo_set.all() -> 一对多关联查询 由多到一的访问语法: "多"的实例对象. "多"模型类 中 <关联的属性_id> h = HeroInfo.objects.get(id=1) -> 得到实例对象 h.hbook_id ->多对一关联查询, 注意是.自身关联属性

<关联过滤查询> 由多模型类条件查询一模型类数据: 关联模型类名小写__属性名__条件运算符 = 值 注意:如果没有"__运算符"部分,表示等于 查询图书,要求图书英雄为"孙悟空" BookInfo.objects.filter(heroinfo__hname=‘孙悟空’) -> (关联模型类名小写__属性名__条件运算符 = 值)

查询图书,要求图书中英雄的描述包含"八"
BookInfo.objects.filter(heroinfo__hcomment__contains=‘八’)
? 查的是什么,那么就是 什么.objects

由一模型类条件查询多模型类数据: 一模型类关联属性名__一模型类属性名__条件运算符=值
查询书名为“天龙八部”的所有英雄。
HeroInfo.objects.filter(hbook__btitle=‘天龙八部’)

查询图书阅读量大于30的所有英雄
	HeroInfo.objects.filter(hbook__bread__gt=30)
? 查的是什么,那么就是 什么.objects

修改 save法 hero = HeroInfo.objects.get(hname=‘猪八戒’) hero.hname = ‘猪悟能’ hero.save() update法 使用模型类.objects.filter().update(),会返回受影响的行数 HeroInfo.objects.filter(hname=‘沙悟净’).update(hname=‘沙僧’)

删除 模型类对象delete hero = HeroInfo.objects.get(id=13) hero.delete() 模型类.objects.filter().delete() HeroInfo.objects.filter(id=14).delete()

定义表单类 新建一个子应用/forms.py文件,编写Form类

from django import forms
class BookForm(forms.Form):
变量名需与前端提供键名的一致
title = forms.CharField(label=“书名”, required=True, max_length=50)
pub_date = forms.DateField(label=‘出版日期’, required=True)

(定义模型类表单:
如果表单中的数据与模型类对应,可以通过继承forms.ModelForm更快速的创建表单。
class BookForm(forms.ModelForm):
class Meta:
model = BookInfo
fields = (‘btitle’, ‘bpub_date’)
model 指明从属于哪个模型类
fields 指明向表单中添加模型类的哪个字段
)

视图中使用表单类
from django.shortcuts import render
from django.views.generic import View
from django.http import HttpResponse
from .forms import BookForm

class BookView(View):
def get(self, request):
form = BookForm()
return render(request, ‘book.html’, {‘form’: form})

def post(self, request):
    form = BookForm(request.POST)
    if form.is_valid():  # 验证表单数据 ->is_valid 继承自 django.forms.Form
        print(form.cleaned_data)  # 获取验证后的表单数据 ->cleaned_data 继承同上 ->out class'dict'
        return HttpResponse("OK")
    else:
        return render(request, 'book.html', {'form': form})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天下·第二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值