from django.db.utils import IntegrityError
from django.http import HttpResponse,JsonResponse
from django.shortcuts import render
import json
from projects.models import Project
from django.forms.models import model_to_dict
# Create your views here.
from django.views import View
from django.views.decorators.csrf import csrf_exempt
class ProjectSingleView(View):
def get(self,request):
# all_projects = Project.objects.all()
# result = all_projects.objects.values() # return ValuesQuerySet object
list_result = [entry for entry in Project.objects.all().values()] # converts ValuesQuerySet into Python list
if('id' in list(request.GET.keys()) and len(list(request.GET.keys())) == 1):
Project.objects.filter(id=request.GET.get('id'))
list_result = [entry for entry in Project.objects.filter(id=request.GET.get('id')).values()] # converts ValuesQuerySet into Python list
# list_result1 = [entry for entry in request.GET.values()] # converts ValuesQuerySet into Python list
return JsonResponse(list_result, safe=False, status=200, json_dumps_params={'ensure_ascii': False})
def post(self,request):
json_Obj = json.loads(request.body.decode("utf-8"))
result_dict = {}
result_dict['result'] = 1
reason = ""
try:
one_pro = Project.objects.create(leader=json_Obj['leader'],desc=json_Obj['desc'],name=json_Obj['name'])
result_dict['reason'] = "添加成功"
except IntegrityError:
result_dict['result'] = 0
result_dict['reason'] = '项目名称不能重复'
return JsonResponse(json.loads(json.dumps(result_dict)),safe=False)
def delete(self,request):
pass
class ProjectView(View):
def get(self,request,pk):
list_result = [entry for entry in Project.objects.filter(pk=pk).values()] # converts ValuesQuerySet into Python list
return JsonResponse(list_result, safe=False, status=200, json_dumps_params={'ensure_ascii': False})
def post(self,request):
pass
def put(self,request,pk):
result_dict = {}
result_dict['result'] = 1
result_dict['reason'] = "修改成功"
body_dict = json.loads(request.body.decode("utf-8"))
try:
for key ,value in body_dict.items():
if key == "desc":
Project.objects.filter(pk=pk).update(desc=value)
elif key == "name":
Project.objects.filter(pk=pk).update(name=value)
elif key == "leader":
Project.objects.filter(pk=pk).update(leader=value)
except BaseException:
result_dict['result'] = 0
result_dict['reason'] = "修改异常"
return JsonResponse(json.loads(json.dumps(result_dict)))
# one_pro = Project.objects.get(pk=pk)
# for key ,value in body_dict.items():
# one_pro.key = value
# one_pro.save()
# for key ,value in body_dict.items():
# print(key,value)
# Project.objects.filter(pk=pk).update(key=value)
def delete(self,request,pk):
result_dict = {}
result_dict['result'] = 1
result_dict['reason'] = "删除成功"
Project.objects.filter(pk=pk).delete()
return JsonResponse(json.loads(json.dumps(result_dict)))
from django.db import models
from utils.BaseModel import BaseModel
# Create your models here.
class Project(BaseModel):
name = models.CharField(unique=True,max_length=200,help_text="项目名称",verbose_name="项目名称")
leader = models.CharField(max_length=50,help_text="项目负责人",verbose_name="项目负责人")
desc = models.TextField(help_text="项目描述",verbose_name="项目描述")
class Meta:
db_table = "tb_project"
verbose_name = "项目表"
from django.db import models
from django.db.models import Model
class BaseModel(models.Model):
id = models.AutoField(primary_key = True,help_text="主键",verbose_name="主键")
create_time = models.DateTimeField(auto_now_add=True,help_text="创建时间",verbose_name="创建时间")
update_time = models.DateTimeField(auto_now=True,help_text="修改时间",verbose_name="修改时间")
class Meta:
abstract = True
from utils.BaseModel import BaseModel
from django.db import models
from projects.models import Project
class Interface(BaseModel):
name = models.CharField(max_length=200,help_text="接口名称",verbose_name="接口名称")
tester = models.CharField(max_length=50,help_text="测试者",verbose_name="测试者")
project = models.ForeignKey(Project,on_delete=models.CASCADE,related_name="interface")
class Meta:
db_table = "tb_interface"
verbose_name = "接口表"
"""
Django settings for dev08 project.
Generated by 'django-admin startproject' using Django 3.2.5.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-n0emb&jl!nt1t(z3&uz2oei-+n2e74z=53wfo*8t-g4czv5m4)'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'projects',
'users',
'interfaces',
# 'projects.apps.ProjectsConfig',
]
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',
]
ROOT_URLCONF = 'dev08.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 指定HTML模板存放的绝对路径
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'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',
],
},
},
]
WSGI_APPLICATION = 'dev08.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
# 'ENGINE': 'django.db.backends.mysql',
'NAME': BASE_DIR / 'db.sqlite3',
# 'NAME': 'db',
# 'USER': 'root',
# 'PASSWORD': '1234567',
# 'PORT': 3306
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
# 指定项目的语言
LANGUAGE_CODE = 'zh-hans'
# 指定项目的时区
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
"""dev08 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path, include
from projects.views import index, get_project, get_project_by_id, get_users
urlpatterns = [
# path('admin/', admin.site.urls),
# path('projects/', index),
# path('projects/<int:ids>/', get_project_by_id),
# path('pro1/', get_project),
# re_path(r'^users/(?P<username>\w{6,12})/$', get_users)
path('projects/', include('projects.urls')),
]
from django.db import models
from utils.base_model import BaseModel
# from projects.models import Projects
# 在关系型数据库中,表与表之间有哪些关系?
# 一对一
# 多对一
# 多对多
# class Interfaces(models.Model):
class Interfaces(BaseModel):
# id = models.IntegerField(primary_key=True, verbose_name='id主键', help_text='id主键')
name = models.CharField(unique=True, verbose_name='接口名称', help_text='接口名称', max_length=15)
tester = models.CharField(verbose_name='接口测试人员', help_text='接口测试人员', max_length=13)
# projects = models.ForeignKey(Projects, )
# a.如果表与表之间为多对一或者一对多关系,那么需要在“多”的那个模型类中定义外键字段
# b.可以使用ForeignKey定义外键
# 》必须指定两个必传参数
# 》第一个参数必须指定所关联的父表
# 第一种方式:将所关联的父表模型类导入,使用父表所在的模型类作为参数
# 第二种方式:使用"父表所在子应用名.父表所在模型类名",作为字符串参数传递
# 》第二个参数必须指定on_delete级联删除策略(当父表数据删除时,父表数据所属从表数据的删除策略)
# models.CASCADE,指定从表数据会自动删除
# models.PROTECT,父表含有从表数据时,会抛出异常
# models.SET_NULL,会设为null
# models.SET_DEFAULT,会设为默认值,必须指定default
# 定义的外键字段,执行迁移之后,会自动创建外键字段名_id作为数据库中外键字段名称
projects = models.ForeignKey('projects.Projects', on_delete=models.CASCADE)
# models.OneToOneField,为一对一关系的表指定外键字段
# models.ManyToManyField,为多对多关系的表指定外键字段
# create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
# update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
class Meta:
db_table = 'tb_interfaces'
verbose_name = '接口表'
verbose_name_plural = '接口表'
ordering = ['id']
def __str__(self):
return f"<{self.name}>"
from django.db import models
from utils.base_model import BaseModel
# class Projects(models.Model):
class Projects(BaseModel):
# a.如果ORM模型类中某个字段指定了primary_key=True,那么ORM框架就不会自动生成名称为id的自增主键
# b.会把指定了primary_key=True的字段作为主键
# c.创建的ORM模型类中字段默认primary_key=False,为非主键字段
# d.verbose_name和help_text指定当前字段的描述信息,一般在api接口文档平台、后台管理站点、前端渲染的表单中会显示
# id = models.IntegerField(primary_key=True, verbose_name='id主键', help_text='id主键')
# e.使用unique=True为当前字段指定唯一约束,默认创建的ORM模型类字段unique=False(可重复)
name = models.CharField(unique=True, max_length=50, verbose_name='项目名称', help_text='项目名称')
# f.使用null=True,指定当前字段可以设为null值,默认创建的字段为非空
leader = models.CharField(null=True, max_length=20, verbose_name='项目负责人', help_text='项目负责人')
# g.使用default=True,为当前字段指定默认值,指定默认值之后,前端创建数据时,如果不指定该字段,那么会自动将默认值作为当前字段的值
is_execute = models.BooleanField(verbose_name='是否启动项目', help_text='是否启动项目', default=True)
# h.使用blank=True,指定前端在创建数据时,可以不用传递该字段(在后面序列化器类中使用),默认前端在创建数据时,必须传递该字段
desc = models.TextField(verbose_name='项目描述', help_text='项目描述', null=True, blank=True, default='')
# i.可以为DateTimeField、DateField字段添加auto_now_add、auto_now参数
# 》auto_now_add=True指定在创建该记录时,会自动将当前创建的时间作为该字段的值,后续不会变更
# 》auto_now=True定在每次更新该记录时,会自动将当前更新的时间作为该字段的值,后续只要更新了该记录,都会自动修改
# 》auto_now_add和auto_now不能同时指定
# create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
# update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
# aaa = models.CharField(max_length=10)
class Meta:
db_table = 'tb_projects'
verbose_name = '项目表'
verbose_name_plural = '项目表'
ordering = ['id']
def __str__(self):
return f"<{self.name}>"
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
@Time : 2021/7/23 20:21
@Auth : 可优
@File : urls.py
@IDE : PyCharm
@Motto: ABC(Always Be Coding)
@Email: keyou100@qq.com
@Company: 湖南省零檬信息技术有限公司
@Copyright: 柠檬班
-------------------------------------------------
"""
from django.urls import path, re_path
# from projects.views import index, get_project
# from .views import index, get_project
from . import views
urlpatterns = [
# path('<int:pk>/', views.get_project),
path('<int:pk>/', views.ProjectView.as_view()),
re_path(r'^users/(?P<username>\w{5,20})/$', views.get_users)
]
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.views import View
from django.db import connection
# from projects.models import Projects
from .models import Projects
from interfaces.models import Interfaces
def index(request):
return HttpResponse('<h1>测试开发8期的大佬大家好!</h1>')
def get_project(request, pk):
# print(type(request))
# print(request)
# return HttpResponse('<h1>这是某某项目</h1>')
if request.method == 'GET':
# 需要从数据库中读取项目数据
return HttpResponse(f'<h1>获取id为{pk}的项目</h1>')
elif request.method == 'POST':
# a.从前端获取项目相关的数据
# b.校验项目数据
# c.将校验之后的项目数据写入到数据库
return HttpResponse(f'<h1>创建id为{pk}的项目</h1>')
elif request.method == 'PUT':
return HttpResponse(f'<h1>更新id为{pk}的项目</h1>')
elif request.method == 'DELETE':
return HttpResponse(f'<h1>删除id为{pk}的项目</h1>')
else:
# return HttpResponse('<h1>项目的其他操作</h1>')
pass
def get_project_by_id(request, ids):
if isinstance(ids, int) and ids < 100:
return HttpResponse(f'这是id为{ids}的项目')
else:
return HttpResponse(f'id为{ids}的项目不存在')
def get_users(request, username):
return HttpResponse(f'Hello, {username}!')
class ProjectView(View):
def get(self, request, pk):
# a.从数据库中读取项目数据
datas = [
# {
# "project_name": "前程贷项目",
# "leader": "可优",
# "app_name": "P2P平台应用"
# },
{
"project_name": "探索火星项目",
"leader": "优优",
"app_name": "吊炸天应用"
},
{
"project_name": "无比牛逼的项目111",
"leader": "可可",
"app_name": "神秘应用"
},
]
# b.数据插入到html模板中
# return HttpResponse(f'<h1>获取id为{pk}的项目</h1>')
# return render(request, 'index.html', locals())
return JsonResponse(datas, safe=False, status=200, json_dumps_params={'ensure_ascii': False})
def post(self, request, pk):
# from django.db import connection
# 一、创建(create)
# 方式一:
# 通过创建模型类对象(对模型类进行实例化)
# 模型类对象必须调用save()才会执行sql语句
# one_project = Projects(name='在线教育项目22', leader='MR.F')
# one_project.save()
# 方式二:
# 模型类.objects.create(字段名1=值1, 字段名2=值2, ...)
# 无需调用save方法,会立即执行sql语句
# one_project = Projects.objects.create(name='某某项目', leader='背影', is_execute=False, desc='xxx描述')
# 创建从表数据
# 方式一:
# 先获取父表模型对象
# one_project = Projects.objects.get(id=1)
# 在创建从表数据时,如果使用外键字段名作为参数名,那么需要传递父表模型对象
# one_interface = Interfaces(name='登录接口', tester='阿柒', projects=one_project)
# 方式二:
# 在创建从表数据时,如果使用外键字段名_id作为参数名,那么需要传递父表模型对象的主键id值
# one_interface = Interfaces(name='登录接口', tester='阿柒', projects_id=one_project.id)
# one_interface.save()
# from random import choice
# from string import ascii_letters, digits
# for i in range(50):
# num_list = [choice(ascii_letters + digits) for _ in range(8)]
# num_str = ''.join(num_list)
# name = f'{num_str}项目'
# Interfaces.objects.create(name=name,
# tester='xxx',
# projects_id=choice([1, 2]))
# 二、更新
# 方式一:
# a.更新一条数据,先获取模型对象,对模型对象中的类属性进行赋值,再调用save方法
# b.只有调用save方法之后,才会执行sql语句
# one_project = Projects.objects.get(id=1)
# one_project.name = '某某移动商城项目11'
# c.ORM框架会为每一个模型类的主键字段设置一个名为pk的别名
# d.当前id与pk是一样的
# one_project.save(update_fields=['name'])
# 方式二:
# 更新所有数据
# 模型类.objects.update(字段名1=值1, 字段名2=值2, ...)
# obj = Projects.objects.update(desc='xxx描述')
# 三、查询(select)
# 1.查询一条数据
# a.使用模型类.objects.get()
# b.如果符合get方法指定的参数的数据条数不为一,那么会抛出异常(数据条数为0或者超过1)
# c.一般会使用具有唯一约束的字段来进行查询
# one_project = Projects.objects.get(id=1)
# 2.查询多条数据
# a.使用模型类.objects.filter(字段名__查询类型=值)
# b.QuerySet对象,类似于列表类型
# c.查询类型种类?
# 》字段名__gt、字段名称__gte、字段名称__lt、__lte、__startwiths、__istartwiths
# __endwiths、__regex、__in、__isnull、__exact
# QuerySet查询集的特性?
# a.惰性查询
# 仅仅只有“用”数据时才会执行sql语句,提升数据库操作性能
# 》在for循环迭代时
# 》使用len函数获取长度时
# 》使用数据索引取值时
# b.链式调用
# QuerySet支持的操作?
# 》支持使用数字(正值)索引取值
# 》支持切片操作
# 》len、list函数
# 》for循环迭代,每次迭代时会取出模型对象
# 》.first()获取QuerySet中的第一个模型对象
# 》.last()获取QuerySet中的最后一个模型对象
# 》.count()获取QuerySet的长度
# 》.exists()判断QuerySet是否为空,如果返回True,代表QuerySet不为空,否则为空
# qs = Projects.objects.filter(pk__lt=3)
pass
response = HttpResponse(f'<h1>创建id为{pk}的项目</h1>', status=500)
response['Content-Type'] = 'application/json'
return response
def put(self, request, pk):
return HttpResponse(f'<h1>更新id为{pk}的项目</h1>')
def delete(self, request, *args, **kwargs):
return HttpResponse(f'<h1>删除id为{kwargs.get("pk")}的项目</h1>')
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
@Time : 2021/7/30 20:16
@Auth : 可优
@File : base_model.py
@IDE : PyCharm
@Motto: ABC(Always Be Coding)
@Email: keyou100@qq.com
@Company: 湖南省零檬信息技术有限公司
@Copyright: 柠檬班
-------------------------------------------------
"""
from django.db import models
class BaseModel(models.Model):
"""
a.主要意义是将不同ORM模型类中的公共字段提取出来
b.用于被子模型类继承
"""
id = models.IntegerField(primary_key=True, verbose_name='id主键', help_text='id主键')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
class Meta:
# c.指定当前模型类为抽象模型类
# d.在执行迁移时,不会生成迁移文件,也不会执行迁移脚本
abstract = True
创建Django项目工程
一、可以
打开已经存在的本地django项目
1.点击“Open”
二、可以通过git仓库下载django项目
1.选择git
2.复制粘贴django项目工程的git仓库地址
三、可以创建新的django项目工程
1.虚拟环境的意义
a.为了不同项目之间能够相互独立
b.不同项目如果使用的同一个模块版本不一致或者使用的python版本不一致
2.创建虚拟环境
a.pipenv、virtualenv等
b.创建步骤
》安装pipenv
pip install -i https://pypi.douban.com/simple pipenv
》方式一:通过专业版本Pycharm点击New,选择pipenv
》方式二:先关联系统解释器,然后再手动创建虚拟环境
pipenv shell
pipenv install django
c.下载django
》修改Pipfile中的url
url = “https://pypi.douban.com/simple”
》安装django
pipenv install django
pip install django
d.安装django项目工程
》django-admin startproject 项目名称
会在terminal所在目录下,创建一个新的独立的django项目工程
》django-admin startproject 项目名称 .
会把terminal所在目录作为django项目的根目录,在此目录下创建项目
》项目名称:建议设置为Python中合法的标识符名称
》.代表在当前目录下创建
3.启动django项目
方式一:
a.打开terminal,进入到虚拟环境汇总
b.python manage.py runserver
会默认在127.0.0.1上监听8000端口
c.python manage.py runserver ip:port(ip:可以省略)
d.使用ctrl + c退出项目
方式二:
a.在Pycharm专业版本上创建django的启动器
b.点击右上角的“Add configuration” -> 点击“+”-> 选择“django” -> 设置启动的名称 -> 下方的“fix”
-> Enable Django support -> 选django项目路径 -> settings.py所在路径
四、django项目工程结构
1.与项目名称同名的目录
dev08/ 用于保存django项目各种配置信息,是一个包
asgi.py 用于启动ASGI协议应用服务器的入口文件,在异步项目部署中使用
settings.py 用于重写、指定django的全局配置信息
urls.py 用于创建全局路由信息
wsgi.py 用于启动WSGI协议应用服务器的入口文件,在项目部署上线时使用
db.sqlite3 django默认的关系型文本数据库文件,一般在开发阶段使用
manage.py 是django中命令行管理工具
五、设置版本管理
方式一:
打开VCS -> Enable Version Control -> git
方式二:
》打开terminal,进入虚拟环境
》git init,会在当前路径下进行版本管理,创建一个.git目录(存放git所有的配置信息)
》创建提交者信息
本地:
git config --local user.name "用户名"
git config --local user.email "用户邮箱地址"
全局:
git config --global user.name "用户名"
git config --global user.email "用户邮箱地址"
》将工作区中的修改添加到暂存区中
git add .
》将暂存区中的数据添加至本地仓库
git commit -m "当前版本的注释信息"
》推送代码到远程的步骤
a.在远程代码托管平台创建项目(如:dev08)
b.git remote add origin 项目地址
c.git push -u origin --all
》创建分支
git checkout -b 分支名称
六、子应用
1.子应用的意义
a.便于复用
b.便于管理
2.子应用的创建
社区/专业版:python manage.py startapp 子应用名
专业版:打开Tools下Run manage Task -> startapp 子应用
3.子应用的注册
a.如果需要django能够正常使用子应用,那么必须的注册
b.settings.py中INSTALLED_APPS列表中进行注册
c.方式一:‘子应用名’ 方式二:‘子应用名.apps.子应用名首字母大写Config’
4.子应用的结构
子应用名/ 为python中的包
admin.py 对后台管理站点进行配置
apps.py 用于配置当前子应用的相关信息
models.py 用于定义数据库模型类
tests.py 用于编写当前子应用的单元测试
views.py 用于定义业务逻辑
七、路由
1.什么是路由?
前端用户请求的url与后端函数(视图函数)的映射条目
2.在哪里定义路由?
a.在与项目名同名包下的urls.py中定义
b.全局路由文件
c.urlpatterns列表中定义路由
3.怎样定义路由?
a.使用调用path函数的形式定义
b.path函数第一个参数为url路径
》url路径,去掉“ip、域名:端口号/”之后,剩余的部分
》url路径前往往无需添加“/”,在url路径最后需要添加“/”
c.path函数第二个参数为待调用的函数名(视图函数名称)
d.如果path函数第二个参数为include函数,那么会继续到include指定的子路由中去匹配
e.include需要添加子路由的路径(“子应用名.urls”)
4.如何寻址?
a.urlpatterns列表从上到下进行匹配
b.如果匹配不成功,会继续往后匹配
c.如果匹配成功,会【自动】调用path函数第二个参数指定的视图函数
d.同时一旦匹配成功会结束匹配
e.如果全部匹配不成功,那么会抛出404异常(404页面)
5.定义路径参数
a.xxx/<类型转化器:参数名称>/
b.自带的类型转化器:int、str、slug、uuid
c.如果路径能与类型转化器进行匹配,那么会把参数作为关键字参数传递给视图函数
d.视图函数是以关键字参数的形式接收的,所有参数名称要与视图函数接收参数的名称保持一致
e.如果类型转化器匹配不成功,会继续往后匹配
八、函数视图
1.函数视图的参数和返回
a.第一个参数为HttpRequest对象
b.当路由匹配成功后,django框架会将前端的请求所有数据封装为HttpRequest,在调用视图函数时自动传递给函数的第一个参数
c.可以使用HttpRequest对象中的method属性获取请求方法名称(大写),可以通过不同的请求方法,执行不一样业务逻辑
b.函数视图必须返回HttpResponse对象或者HttpResponse子类的对象
2.函数视图的弊端
a.代码冗余严重
b.代码复用性差
3.调试
a.断点:以调试模式启动django项目,当代码执行到断点标记的地方,会自动暂停
b.意义:快速排错、快速阅读源码、快速开发代码
c.打断点的注意事项:一般断点打在函数或者方法体内部、尽量不要打在跨越多行的代码
九、类视图
1.定义
a.必须得继承View父类或者View子类
b.不同的请求方法是以实例方法来实现的
c.实例方法名与请求方法的对应关系
get -> GET
post -> POST
put -> PUT
delete -> DELETE
patch -> PATCH
d.每一个实例方法需要返回HttpResponse对象或者HttpResponse子类的对象
e.如果类视图中未定义相应的实例方法,会报405异常
2.路由条目
a.path函数的第一个参数为类视图.as_view()
十、django中的请求
1.请求参数类型
a.路径参数
》在url路径上传递的参数,如:path(‘xxx/int:parameter/’)
》在函数视图或者类视图的实例方法中使用关键字作为参数名去接收
b.query string查询字符串参数
》http://xxx.com/?key1=value1&key2=value2&key1=value3
》使用request.GET属性获取
》request.GET返回QueryDict对象,是一个like-dict类字典类型,与字典类似(但区别)
》使用request.GET['key']或者request.GET.get('key'),如果多个参数中有名称相同的参数,获取的是最后一个值
》使用request.GET.getlist('key')去获取有名称相同的参数所有值,返回列表类型
c.请求体参数
》application/x-www-form-urlencoded
# 使用request.POST获取
# request.POST返回QueryDict对象,是一个like-dict类字典类型,与字典类似(但区别)
# 使用request.POST['key']或者request.POST.get('key'),如果多个参数中有名称相同的参数,获取的是最后一个值
# 使用request.POST.getlist('key')去获取有名称相同的参数所有值,返回列表类型
》application/json
# 在request.body中提取数据(json字节数据)
# json.loads(request.body, encoding='utf-8)
# loads、load、dump、dumps
》multipart/form-data
# 可以传递文本参数和文件参数
# 传递的文本参数可以使用request.POST获取
# 创建的文件参数可以使用request.FILES获取,为MultiValueDict(是一个like-dict类型)
》xml、text
# 在request.body中提取数据
d.请求头参数
》可以使用request.META获取参数
# 所有的参数名称被修改为:HTTP_请求头参数名全大写(如果有“-”,会转化为“_”)
》request.headers获取参数
# 可以直接使用请求头参数名获取
# 忽略大小写
十一、查看python源码
1.将光标定位在待查看的类或者函数上,ctrl + b
2.或者使用ctrl + 鼠标左键
十二、django中的响应(HttpResponse、JsonResponse)
1.第一个参数可以传递返回给前端的字符串或者字节数据
2.status关键字参数传递响应状态码,默认为200
3.headers关键字参数传递响应头信息(字典类型)
4.content_type关键字参数传递响应头中的Content-Type
5.可以使用类似字典添加key-value的形式,指定响应头数据(如:response[‘Content-Type’] = ‘application/json’)
6.JsonResponse第一个参数为字典或者嵌套字典的列表
7.JsonResponse第一个参数为嵌套字典的列表,必须设置safe=False
十三、ORM框架
1.使用pymysql执行原生sql语句的痛点
a.sql语句比较复杂且不便于管理
b.sql语句安全性无法保证
c.数据表创建、修改、更新、数据添加以及数据的迁移操作是比较麻烦的
d.数据表中添加索引、视图比较困难
e.sql语句性能不够好
2.ORM框架的意义
a.可以解决上述所有的痛点
b.可以大大地提升开发效率
c.也可以直接执行原生的sql语句
3.mysql中有哪些对象?
a.数据库
# 需要先安装mysql
# 再手动创建数据库(create databases 数据库名 charset=utf8mb4;)
b.数据表
# 与ORM框架中的模型类一一对应
# 一个ORM模型类就是一张数据表
# 在子应用models.py中定义模型类
c.字段
# 与ORM模型类中的类属性一一对应
d.记录
# 与ORM模型类中对象