2021-08-02

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模型类中对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值