首页 > 其他分享 >学习日记之《Django3 Web应用开发实战》

学习日记之《Django3 Web应用开发实战》

时间:2024-03-31 22:31:45浏览次数:23  
标签:Web name 视图 django context mysql import Django3 日记

学习日记之《Django3 Web应用开发实战》

第二章——Django 配置信息

1、静态资源和媒体资源

# settings.py
# Django只能识别项目应用APP的static文件夹的静态资源,这是由INSTALLED_APPS->django.contrib.staticfiles实现的
STATIC_URL = '/static/'   # 静态资源路由  

# 资源集合,列表中可设置多个访问静态资源的地址
STATICFILES_DIRS = [ BASE_DIR / 'StaticFiles']

# STATIC_ROOT主要收集整个项目的静态资源并存放在一个新的文件夹,然后由该文件夹与服务器之间构建映射关系
# 当项目的配置属性DEBUG设为True的时候,Django会自动提供静态文件代理服务(STATIC_URL),此时整个项目处于开发阶段,因此无须使用STATIC_ROOT。当配置属性DEBUG设为False的时候,意味着项目进入生产环境,Django不再提供静态文件代理服务,此时需要在项目的配置文件中设置STATIC_ROOT。
# 设置STATIC_ROOT需要使用Django操作指令collectstatic来收集所有静态资源,这些静态资源都会保存在STATIC_ROOT所设置的文件夹里。
STATIC_ROOT = BASE_DIR / 'Allstatic'  # 资源部署

# 媒体资源:存放媒体信息,如音视频,文件等
MEDIA_URL = "/media/"  # 媒体路由地址
MEDIA_ROOT = BASE_DIR / "media"  # 媒体路径信息

# 项目urls.py 设置
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static
from django.conf import settings
from django.views.static import serve

方式一
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
or
方式二
urlpatterns += [re_path("media/(?P<path>.*)", serve, {
   "document_root": settings.MEDIA_ROOT}, name='media')]

2、模板配置

TEMPLATES = [
    {
   
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR, 'templates'],   # 可自定义模板的位置 名称 templates 固定
        'APP_DIRS': True,  # 默认可以识别每个应用下的 templates
        'OPTIONS': {
   
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

3、数据库配置

连接mysql举例:

安装
pip3 install pymysql

在项目(和settings.py同目录)下的__init__.py设置
import pymysql
pymysql.install_as_MySQLdb()   # 设置数据库连接模块即可

MySQL配置方式

方式一:直接配置
DATABASES = {
   
    'default': {
   
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db',   # 提前在MySQL中创建该名称的数据库
        'USER':'root',    # MySQL登录的用户名
        'PASSWORD': '123',   # MySQL登录的密码
        'HOST':'127.0.0.1',  
        'PORT':'3306',
    }
}
方式二:动态配置数据库连接
先创建一个连接数据库的配置信息,比如my.cnf
填写如下内容:
[client]
database=django_db
user=root
password=123
host=127.0.0.1
port=3306

DATABASES = {
   
    'default': {
   
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS':{
   'read_default_file':str(BASE_DIR / 'my.cnf')},
    }
}

多数据库连接配置
多数据库下,如果没有指定具体存储到那个数据库,默认存储到default名的数据库下。
DATABASES = {
   
    # 第一个数据库
    'default': {
   
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db0',
        'USER':'root',
        'PASSWORD': '123',
        'HOST':'127.0.0.1',
        'PORT':'3306',
    },
    # 第二个数据库
    'mydjango': {
   
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'django_db1',
            'USER':'root',
            'PASSWORD': '123',
            'HOST':'127.0.0.1',
            'PORT':'3306',
        }
}

通过SSH隧道远程连接数据库
pip3 install sshtunnel

# 设置settings.py
# 数据库服务器的IP地址或主机名
ssh_host = 'XXX.XXX.XXX.XXX'
# 数据库服务器的SSH连接端口号,一般是22,必须是数字
ssh_port = 22
# 数据库服务器的用户名
ssh_user = 'root'
# 数据库服务器的密码
ssh_password = '123'

# 数据库服务器的mysql的主机名或IP
mysql_host = 'localhost'
# 数据库服务器的mysql的端口,默认是3306
mysql_port = 3306
# mysql的用户名
mysql_user = 'root'
# mysql的密码
mysql_password = '123'
# mysql的数据库名
mysql_db = 'mydjango'

from sshtunnel import open_tunnel

def get_ssh():
    server = open_tunnel(
        (ssh_host, ssh_port),
        ssh_username=ssh_user,
        ssh_password=ssh_password,
        # 绑定服务器的mysql数据库
        remote_bind_address=(mysql_host, mysql_port)
    )
    server.start()
    return str(server.local_bind_port)



DATABASES = {
   
    'default': {
   
        'ENGINE': 'django.db.backends.mysql',
        'NAME': mysql_db,
        'USER':mysql_user,
        'PASSWORD': mysql_password,
        'HOST':mysql_host,
        'PORT':get_ssh(),
    }
}

4、中间件介绍

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',  # 内置安全机制,保护用户和网络的通信安全
    'django.contrib.sessions.middleware.SessionMiddleware',  # 会话Session功能
    'django.middleware.locale.LocaleMiddleware',   # 国际化和本地化中间件
    'django.middleware.common.CommonMiddleware',  # 处理请求信息,规范化请求内容
    'django.middleware.csrf.CsrfViewMiddleware',  # 开启CSRF防护功能
    'django.contrib.auth.middleware.AuthenticationMiddleware',  # 开启内置的用户认证系统
    'django.contrib.messages.middleware.MessageMiddleware',  # 开启内置的信息提示功能
    'django.middleware.clickjacking.XFrameOptionsMiddleware',  # 防止恶意程序单机劫持
]

第三章——初探路由

1、反向解析

from django.shortcuts import reverse   # 生成路由地址
from django.urls import resolve  # 通过路由地址生成路由对象

reverse('index:mydate', args=args)
reverse('index:mydate', kargs=kargs)

result= resolve(reverse('index:mydate', args=args))  # 了解一下生成的对象有哪些方法和属性

2、重定向

from django.shortcuts import redirect   # 指定跳转到指定的路由地址

redirect(reverse('index:mydate', args=args))   # 一种方式是使用路由
redirect('index:mydate', permanent=True)   # 一种方式是使用路由命名,可以指定是否永久重定向

第四章——探究FBV视图

1、异常响应

Django配置全局异常响应
注意:必须在项目名的urls.py下配置
项目下的urls.py
# 全局404页面配置
handler404 = 'index.views.page_not_found'   # 连接到指定的路由处理
# 全局500页面配置
handler500 = 'index.views.page_error'  # 连接到指定的路由处理

验证是否生效:需要在settings.py 设置DEBUG=False 和 ALLOWED_HOSTS=['*']

2、文件下载功能

# views.py
import os

from django.shortcuts import render
from django.http import HttpResponse, Http404
from django.http import StreamingHttpResponse
from django.http import FileResponse

# Create your views here.
def index(request):
    return render(request, 'index.html')


file_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

file_path1 = file_path + '/media/cat1.png'
file_path2 = file_path + '/media/cat2.png'
file_path3 = file_path + '/media/cat3.png'
def download1(request):
    try:
        r = HttpResponse(open(file_path1, 'rb'))
        r['content_type'] = 'application/octet-stream'
        r['Content-Disposition'] = 'attachment;filename=cat1.png'
        return r
    except Exception:
        raise Http404("Download error")

def download2(request):
    try:
        r = StreamingHttpResponse(open(file_path2, 'rb'))
        r['content_type'] = 'application/octet-stream'
        r['Content-Disposition'] = 'attachment;filename=cat2.png'
        return r
    except Exception:
        raise Http404("Download error")

def download3(request):
    try:
        f = open(file_path3, 'rb')
        r = FileResponse(f, as_attachment=True, filename='cat3.png')
        return r
    except Exception:
        raise Http404("Download error")

说明:
HttpResponse:不建议使用,消耗内存
StreamingHttpResponse:建议使用,支持大规模数据或者文件输入,需提供数据格式和文件格式
FileResponse:仅支持文件输入

3、文件上传功能

无论上传的文件是什么格式,其上传原理都是将文件以二进制的数据格式读取并写入网站指定的文件夹里

# views.py
def upload(request):
    if request.method == "POST":
        myFile = request.FILES.get("myfile", None)
        if not myFile:
            return HttpResponse("no file")

        f = open(os.path.join(upload_path, myFile.name), 'wb+')
        for chunk in myFile.chunks():
            f.write(chunk)
        f.close()
        return HttpResponse("upload over")
    else:
        return render(request, "upload.html")
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Upload</title>
</head>
<body>
<form enctype="multipart/form-data" action="{%url 'test_app:upload'%}" method="post">
  {
   % csrf_token %}
  <input type="file" name="myfile" />
  <br>
  <input type="submit" value="上传文件" />
</form>
</body>
</html>
关键点:enctype="multipart/form-data" 和 文件对象 type="file" name="myfile"
django 通过 request.FILES 获取该文件对象
for chunk in myFile.chunks():
     f.write(chunk)
通过响应流的方式写入文件

自定义上传功能

# 自定义handler.py 
from django.core.files.uploadhandler import *
from django.core.files.uploadedfile import *

class MyFileUploadHandler(TemporaryFileUploadHandler):
    def new_file(self, *args, **kwargs):
        super().new_file(*args, **kwargs)
        print("this is my FileUploadHandle")
        self.file = TemporaryUploadedFile(self.file_name,
                                               self.content_type,
                                               0,
                                               self.charset,
                                               self.content_type_extra)


# settings.py
# 配置文件数据临时存放的文件夹
FILE_UPLOAD_TEMP_DIR = upload_path
# 判断文件大小的条件
FILE_UPLOAD_MAX_MEMORY_SIZE = 209715200
# 配置文件上传的处理过程
FILE_UPLOAD_HANDLERS = ['web_test.handler.MyFileUploadHandler']

关于获取cookie

def create(request):
    r = redirect(reverse('test_app:index'))
    # r.set_cookie('uid', 'cookie_value')
    r.set_signed_cookie('uuid', 'id', salt='my', max_age=60)   # 设置  加密了
    print('i am here')
    return r

def mycookie(request):
    cookie = request.COOKIES.get('uuid', '')  # 获取
    if cookie:
        try:
            m = request.get_signed_cookie('uuid', salt='my')
            print('m', m)
        except:
            raise Http404('当前cookie无效')
        return HttpResponse(f"cookie {
     cookie}")
    else:
        return HttpResponse('hello world')

自定义加解密引擎

# mysigner.py
from django.core.signing import TimestampSigner

class MyTimestampSigner(TimestampSigner):
    def sign(self, value):
        print(value)
        return value + 'Test'

    def unsign(self, value, max_age=None):
        print(value)
        return value[0:-4]

# settings.py
# 默认的Cookie加解密引擎
# SIGNING_BACKEND = 'django.core.signing.TimestampSigner'
# 自定义cookie加解密引擎
SIGNING_BACKEND = 'web_test.mysigner.MyTimestampSigner'

第五章——CBV视图

数据显示视图

RedirectView 重定向视图

class TurnTO(RedirectView):
    permanent = False
    url = 'http://192.168.241.128:8080/download/file1'  # 重定向的路地址
    # pattern_name = 'test_app:index'  # 重定向的路由地址,由路由命名 和url 二选一
    query_string = True  # 是否将当前路由的请求参数传到重定向的地址

    def get_redirect_url(self, *args, **kwargs):
        print('i am here')
        return super().get_redirect_url(*args, **kwargs)

    def get(self, request, *args, **kwargs):
        print('hello world.')
        return super().get(request, *args, **kwargs)

基础视图 TemplateView

from django.views.generic.base import TemplateView

class Index(TemplateView):
    template_name = 'index1.html'
    template_engine = None
    content_type = None
    extra_context = {
   'title': 'this is get'}

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['value'] = 'Django'
        return context

    def post(self, request, *args, **kwargs):
        self.extra_context = {
   'title': 'this is post'}
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

列表视图 ListView

from django.views.generic import ListView
from .models import PersonInfo

class PersonInfoView(ListView):
    template_name = 'personinfo.html'
    extra_context = {
   'title': "人员信息表"}
    queryset = PersonInfo.objects.all()
    paginate_by = 1  # 每页展示的数据
    context_object_name = 'personinfo'  # 模板上下文

详细视图 DetailView

from django.views.generic import DetailView

class PersonInfoDetailView(DetailView):
    template_name = 'info.html'
    extra_context = {
   'title': "人员信息表"}
    slug_field = 'age'  # 模型的查询字段
    slug_url_kwarg = 'age'  # 结合slug_field实现模型查询操作
    pk_url_kwarg = 'pk'
    model = PersonInfo
    context_object_name = 'personinfo'
    query_pk_and_slug = False

数据操作视图

from django.views.generic.edit import FormView
from .form import PersonInfoForm

def result(request):
    return HttpResponse('success')

class ShowForm(FormView):
    initial = {
   'name': 'cooper', 'age': 20}
    template_name = 'show.html'
    success_url = '/result'
    form_class = PersonInfoForm
    extra_context = {
   'title': '人员信息表'}

from django.views.generic.edit import CreateView

class CreateForm(CreateView):
    initial = {
   'name': 'cooper', 'age': 21}
    template_name = 'show.html'
    success_url = '/result'
    model = PersonInfo
    fields = ['name', 'age']
    extra_context = {
   "title": "人员信息表"}


from django.views.generic.edit import UpdateView

class UpdateForm(UpdateView):
    template_name = 'show.html'
    success_url = '/result'
    model = PersonInfo
    fields = ['name', 'age']
    slug_url_kwarg = 'age'
    slug_field = 'age'
    context_object_name = 'personinfo'
    extra_context = {
   'title': '人员信息表'}

from django.views.generic.edit import DeleteView
class DeleteForm(DeleteView):
    template_name = 'show.html'
    success_url = '/result'
    model = PersonInfo
    context_object_name = 'personinfo'
    extra_context = {
   'title': '人员信息表'}
    pk_url_kwarg = 'pk'

日期筛选视图

from .models import TimeInfo
from django.views.generic.dates import MonthArchiveView

class MonthView(MonthArchiveView):
    allow_empty = True
    allow_future = True
    context_object_name = 'mylist'
    template_name = 'time.html'
    model = TimeInfo
    date_field = 'hiredate'
    queryset = TimeInfo.objects.all()
    year_format = '%Y'
    month_format = '%m'
    paginate_by = 50

第六章——深入模板

自定义模板标签和自定义过滤器

# 项目目录下自定义文件夹如mytags,在mytags下创建templatestags(固定)文件夹,创建自定义标签功能
from django import template

# 创建模板对象
register = template.Library()

# 定义模板节点类
class ReversalNode(template.Node):
    def __init__(self, value):
        self.value = str(value)

    def render(self, context):
        return self.value[::-1]

# 声明并定义标签
# parse:解析器对象, token:被解析的对象
@register.tag(name='reversal')
def do_reversal(parse, token):
    try:
        tag_name, value = token.split_contents()
        # tag_name: 标签名   value: 标签传递的数据
    except:
        raise template.TemplateSyntaxError('syntax')
    # 调用自定义的模板节点类
    return ReversalNode(value)


@register.filter(name='replace')
def do_replace(value, args):
    oldvalue = args.split(':')[0]
    newvalue = args.split(':')[1]
    return value.replace(oldvalue, newvalue)

# 模板文件前load 自定义标签
<!DOCTYPE html>
{
   % load custom_tags %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{
   % reversal 'Django' %}   # 自定义标签
{
   {
    value | replace:'Python:Django' }}  # 自定义过滤器
</body>
</html>

Jinja2模板引擎

pip3 install Jinja2
# 和settings.py 同目录创建jinja2_cus.py, 作用:将jinja2模板加载到django 项目中
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
from jinja2 import Environment

# 将jinja2 模板设置到项目环境
def environment(**option):
    env = Environment(**option)
    env.globals.update({
   
        'static': staticfiles_storage.url,
        'url': reverse,
    })
    return env
settings.py
TEMPLATES = [
    # 使用jinja2 模板引擎
    {
   
        'BACKEND': 'django.template.backends.jinja2.Jinja2',
        'DIRS': [BASE_DIR, 'templates'],
        'APP_DIRS'

标签:Web,name,视图,django,context,mysql,import,Django3,日记
From: https://blog.csdn.net/cooper_wx/article/details/136035763

相关文章

  • NSSRound#20 Basic-web专项
    首先是难以评价的web签到。给了个假页面,出题人发了blog可以看看:NSSCTFRound#20Basic真亦假,假亦真CSDN_To_PDFV1.2出题笔记(附wp+源码)-CSDN博客看起来是php,结果是java写的(emmmmmmm....出题人你6,还真是无java不web啊),让我想起了冬季春秋杯有个题,也是php的页面,但是是python写......
  • web前端之页面逐渐呈现代码功能、对象数据如何获取下一个值、创建元素并添加id与类名
    MENU前言style(全部代码)JavaScript(核心代码)html(基本代码)前言1、效果演示以视频为准,暂未录视频(敬请期待);2、私信或微信可获取完整代码(WX:MJ682517)style(全部代码)*{margin:0;padding:0;box-sizing:border-box;}::-webkit-scrol......
  • JavaWeb学习笔记——第十天
    Springboostweb案例(一)准备工作需求说明需要完成以下功能:部门管理员工管理查询部门列表查询员工列表(分页、条件)删除部门删除员工新增部门新增员工修改部门修改员工环境搭建项目架构:准备数据库表(dept、emp)。--部门管理createtabledep......
  • 【研发日记】Matlab/Simulink开箱报告(十一)——Requirements Toolbox
    目录前言RequirementsToolbox编写需求需求联接设计需求跟踪开发进度追溯性矩阵分析和应用总结前言        见《开箱报告,SimulinkToolbox库模块使用指南(六)——S-Fuction模块(TLC)》        见《开箱报告,SimulinkToolbox库模块使用指南(七)——S-Fu......
  • Web系统开发之——文章管理
    原文地址:Web系统开发之——文章管理-Pleasure的博客下面是正文内容:前言经过一番考量,关于Web应用系统功能部分的开发,决定采取基础的文字文章管理为核心功能。不再采取前后端分阶段完成的方式,而是以一个一个细节操作为单位,同时进行前端页面的架构以及后端工程的连接。......
  • 快速上手web前端开发(超详细教程)
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言第一步下安装vscode第二步vscode汉化第三步安装前端所需插件1.LiveServer2.JavaScriptCodeSnippets3.HTMLBoilerplate第四步编辑HTML1.建立一个HTML文件夹,在vscode中打开该文件夹......
  • Web墨卡托投影介绍,Web墨卡托投影和普通墨卡托投影有什么区别?EPSG:3857坐标系和EPSG:43
    Web墨卡托投影和普通墨卡托投影在本质上是相同的,但它们在坐标范围使用单位和应用领域上存在一些区别:坐标范围:普通墨卡托投影的坐标范围通常在整个地球表面上,由于使用浮点数表示,所以不限制其范围。Web墨卡托投影的坐标范围通常被限制在一个固定的范围内,以适应Web地图的显......
  • 《手把手教你》系列技巧篇(六十二)-java+ selenium自动化测试-RemoteWebDriver让你的代
    1.简介当本机上没有浏览器,需要远程调用浏览器进行自动化测试时,需要用到RemoteWebDirver。宏哥申请服务器还没有下来,也懒得自己在本地安装虚拟机,等的时间太长了于是就网上找了一个可以免费试用2天的服务器(网址:DedicatedServerHostingService|BareMetal|Varidata),注册一......
  • Leetcode算法训练日记 | day9
    一、实现strStr函数1.题目Leetcode:第28题给你两个字符串haystack和needle,请你在haystack字符串中找出needle字符串的第一个匹配项的下标(下标从0开始)。如果needle不是haystack的一部分,则返回 -1。示例1:输入:haystack="sadbutsad",needle="sad"输......
  • “依”本日记(三)数据库设计和创建注册功能
    一、数据库设计删除掉原型的user表DROPTABLEuser; 新建数据库添加需要的列,设置好主键,主要有以下几种 --auto-generateddefinitioncreatetableuser(idbigintauto_incrementcomment'id',usernamevarchar(256)......