• 一文帮助快速入门Django


    创建django项目

    指定版本安装django:pip install django==3.2

    命令行创建django项目:

    1. 先进入到要保存项目的目录中
    2. 然后执行:django-admin startproject 项目名

    可以看到创建了这么些文件:

    在这里插入图片描述

    • manage.py:项目的管理工具
    • wsgi.py:提供同步的socket服务
    • asgi.py:异步
    • urls.py:主路由
    • settings.py:配置文件,只有一部分,程序启动时会先读取django内部的配置,再读取该文件的配置

    内部配置文件路径:

    在这里插入图片描述
    在这里插入图片描述

    编写示例代码:

    from django.urls import path
    from django.shortcuts import HttpResponse
    
    # 调此函数会带一个request参数,可使用request获取请求数据
    def login(request):
        # django的响应是一个封装的对象
        return HttpResponse('登录成功')
    
    urlpatterns = [
        # path("admin/", admin.site.urls),
        path('user/login', login) # 只能写函数名
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行:python manage.py runserver
    指定端口运行:python manage.py runserver 127.0.0.1:8080

    执行运行命令前先进入项目目录
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    应用app

    将项目分成不同的功能模块,每个模块对应一个app应用

    创建app:进入项目目录执行python manage.py startapp 应用名

    在这里插入图片描述

    多app的创建:

    1. 在项目目录下创建apps目录,在apps目录下创建以要创的app名为名称创建目录
      在这里插入图片描述
    2. 执行:python manage.py article apps/article
      在这里插入图片描述
    3. 修改该文件内容
      在这里插入图片描述
    4. 注册app
      在这里插入图片描述

    调整示例代码结构:

    在user应用中的views.py文件编写下列代码:

    from django.shortcuts import HttpResponse
    
    def login(request):
        return HttpResponse('login success')
    
    def register(request):
        return HttpResponse('register fail')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    修改urls.py文件的路由配置

    from django.urls import path
    from user import views
    
    urlpatterns = [
        # path('admin/', admin.site.urls),
        path('login/', views.login),
        path('register/', views.register)
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    启动项目,访问
    在这里插入图片描述

    配置pycharm

    配置pycharm启动django项目:

    在这里插入图片描述

    虚拟环境

    使用命令行创建虚拟环境:python官方用于创建虚拟环境的工具:python3.8 -m venv xxx
    该命令会基于系统python环境创建出一个虚拟环境,xxx为名称或目录

    使用第三方工具:virtualenv,先安装:pip install virtualenv
    创建:virtualenv xxx --python=python3.8
    激活:

    • win:
      cd venv/Scripts
      activate
    • mac:
      source /venv/bin/activate

    退出虚拟环境:deactivate

    打包依赖

    pip freeze > requirements.txt

    在这里插入图片描述
    安装依赖:pip install -r requirements.txt

    路由

    传统路由

    路由系统主要是维护url与函数的映射关系

    url中包含参数:

    path('user/gethead//', views.get_head)
    
    • 1

    类型:

    • int,整数
    • str,字符串,但不能匹配/
    • slug,字母,数字,下划线,-
    • uuid,uuid的格式
    • path,路径,可包含/
        path('article/del//', delete),
        path('article/del//', delete),
        path('article/del//', delete),
        path('article/del//', delete),
    
    • 1
    • 2
    • 3
    • 4

    直接在函数中添加参数可获取值

    def get_head(request, id):
        return HttpResponse(id)
    
    • 1
    • 2

    在这里插入图片描述

    路由中包含正则,path替换为re_path

    def article(request):
        id = request.GET.get('id')
        return HttpResponse(id)
    
    • 1
    • 2
    • 3

    注意:参数id字段要一致
    在这里插入图片描述

    include路由分发

    导包include
    主路由:

    	from django.urls import path, include
        # 路由匹配到前缀为user,则分发给apps.user中的urls,include中为路径字符串
        path('user/', include('apps.user.urls')),
        path('article/', include('apps.article.urls'))
    
    • 1
    • 2
    • 3
    • 4

    在user应用中创建urls文件,然后编写路由规则

    urlpatterns = [
        path('add/', views.login)
    ]
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    效果:会先找到主路由user/,然后在分发的文件中匹配到add/,完整的路由为user/add/

    手动路由分发

        path('user/', ([
            path('del/', views.login),
            path('insert/', views.insert)
                       ], None, None)) # 第一个None为app_name,第二个None为namespace
    
    • 1
    • 2
    • 3
    • 4

    匹配的url为:user/del/,user/insert/
    在这里插入图片描述
    include的本质

    name = 'zs'
    
    # 相当于导包 from apps.user import urls
    module = importlib.import_module("apps.user.urls")
    # 也可以使用module.name获取name的值
    # 从module中获取name的值,如果获取不到则默认为ls
    n = getattr(module, 'name', 'ls')
    n = getattr(module, 'name') # 获取不到会直接报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    name

    给路由起名字,可以通过名字反向生成url

        path('user/login/', views.login, name='v1'),
        path('user/register/', views.register, name='v2')
    
    • 1
    • 2
    def login(request):
        # 在这个视图里,需要重定向到register里,就可以不写url,直接使用name即可
        from django.urls import reverse # 需要导包
    
        url = reverse('v2')
        return redirect(url) # 重定向,里面是url地址,使用name反推出的url,不用填写真是的url地址
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    namespace

    用来辅助name的,当出现同名的name时,使用name反推出url可能会出现问题,这时候就可以使用namespace来区分不同的name

        path('user/', include('apps.user.urls', namespace='user'))
    
    • 1
       path('login/', views.login, name='v1'),
       path('register/', views.register, name='v2')
    
    • 1
    • 2
    def login(request):
        # 在这个视图里,需要重定向到register里,就可以不写url,直接使用name即可
        from django.urls import reverse # 需要导包
        
        url = reverse('user:v1') # namespace名:name名
        return redirect(url) # 重定向,里面是url地址,使用name反推出的url,不用填写真是的url地址
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用namespace时,必须提供app_name

    from django.urls import path
    from apps.user import views
    
    urlpatterns = [
       path('login/', views.login, name='v1'),
       path('register/', views.register, name='v2')
    ]
    
    app_name = 'user'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果不提供,会报错
    在这里插入图片描述

    也可以主动去进行路由分发

        path('user/', ([
            path('login/', views.login, name='v1')
        ], 'user', 'user')) # 第一个user为app_name,第二个user为namespace
    
    • 1
    • 2
    • 3

    路由中尾部的/
    路由中带/,但是url不带/访问:127.0.0.1:8000/login

    path('login/', views.login)
    
    • 1

    在这里插入图片描述
    会发现其实是进行了两次请求,第一次找不到路经,django自动将/加上再访问一次

    这个是由于配置文件中默认APPEND_SLASH=True导致的

    如果想严格控制url,可以在settings文件中添加APPEND_SLASH=False

    在这里插入图片描述
    再进行访问
    在这里插入图片描述

    在这里插入图片描述

    当前url的匹配对象
    通过request.resolver_match获取

    def login(request):
        cur_obj = request.resolver_match
        print(cur_obj)
        return HttpResponse('login')
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    拿到这个有什么用?可以做权限处理

        path('login/', views.login, name='test')
    
    • 1
    def login(request):
        permissions = ['user', 'article', 'music'] #用户具有的权限,都是name
        cur_obj = request.resolver_match.url_name #获取当前请求的name
        if cur_obj not in permissions:
            return HttpResponse('没有权限')
        print(cur_obj)
        return HttpResponse('login')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    视图

    一般功能多的时候,这样创建视图文件
    在这里插入图片描述
    通过request对象获取请求内容

    def login(request):
        print(request.path_info) # 请求url
        print(request.GET.get('username')) # 获取get请求参数
        print(request.GET.get('passowrd'))
        print(request.headers) # 请求头   字典类型
        print(request.COOKIES) # cookie  字典类型
        print(request.method) # 请求方法
    
        print(request.body) # 原始请求体
    
        # 获取post请求参数
        # 只针对body格式为a=123&b=abc,且content-type为from表单格式(application/x-www-from-urlencoded)
        print(request.POST.get('username'))
        print(request.POST.get('password'))
    
        # 获取文件 请求头为multipart/form-data
        request.FILES.get('name1')
        request.FILES.get('name2')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    返回数据:

    1. 返回字符串/字节/文本数据
    return HttpResponse('xxx')
    
    • 1
    1. 返回json数据
    def hello(request):
        from django.http import JsonResponse
        ret_dict = {
            'code': 200,
            'data': 'xxx'
        }
        return JsonResponse(ret_dict)
        #return HttpResponse(json.dumps(ret_dict)) 使用json库
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 重定向
    return redirect('https://www.baidu.com') # 参数为url或者url的name
    
    • 1

    设置响应头

        ret = HttpResponse('hello world')
        ret['auto'] = 'true'
        ret['name'] = 'zs'
        ret.set_cookie('key', 'value')
        return ret
    
    • 1
    • 2
    • 3
    • 4
    • 5

    中间件

    MiddlewareMixin
    在项目根目录下,创建middlewares目录,在该目录里创建自定义中间件
    在这里插入图片描述

    from django.utils.deprecation import MiddlewareMixin
    
    class MyMiddleware(MiddlewareMixin):
        def process_request(self, request):
            print('调用视图前')
        def process_response(self, request, response):
            print('调用视图后')
            return response
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    创建完中间件必须在settings文件中进行注册,中间件是以类定义的
    在这里插入图片描述
    当在process_request函数中有返回值的时候,那么不会进入视图函数的执行而是接着执行process_response函数

    注意:路由匹配是在执行完process_request函数后才匹配到的,也就是process_request函数的request参数为None

    process_view

    	# view_func是匹配到的路由函数,view_args,view_kwargs是路由的参数
        def process_view(self, request, view_func, view_args, view_kwargs):
            print(request, view_func)
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    如果想在前置操作中根据视图函数做一些逻辑可以使用process_view

    process_exception

        # 当视图中出现异常时,会捕获到
        def process_exception(self, exception):
            print(exception)
    
    • 1
    • 2
    • 3

    orm关系对象映射

    对表的操作(表的创建,修改,删除)
    对数据的操作(增删改查)

    操作表

    在app的models.py文件创建类,一个类就对应一个表结构

    1. 按照规则创建类
    from django.db import models
    # 生成的表名默认为user_userinfo(app名_类名小写)
    class UserInfo(models.Model):
    	# 默认会生成一个字增主键id
        name = models.CharField(max_length=10)
        age = models.IntegerField()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 注册app(根据注册的app找migrations目录,可以将用不到的app去掉,避免创建使用不到的表)
    2. 执行命令python manage.py makemigrations
      会自动在app目录下的migrations目录下创建一个配置文件
      在这里插入图片描述
    3. 执行命令python manage.py migrate,根据配置文件转换sql语句,链接数据库,执行sql

    执行上述命令前,先进行下面的数据库配置

    数据库配置

    先安装链接mysql的库pymysql/mysqlclient,pip install pymysql
    在settings文件中将默认的数据库配置修改下

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'blog', # 数据库名
            'USER': 'root',
            'PASSWORD': '12345678',
            'HOST': '127.0.0.1',
            'PORT': '3306',
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用pymysql时,在settings文件的同级目录init文件中添加如下内容

    import pymysql
    pymysql.install_as_MySQLdb()
    
    • 1
    • 2

    在这里插入图片描述

    注意:不要手动修改表结构,如果要修改可以修改models文件中的字段,再执行上述的两条命令

    数据库连接池
    pip install django-db-connection-pool

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'blog', # 数据库名
            'USER': 'root',
            'PASSWORD': '12345678',
            'HOST': '127.0.0.1',
            'PORT': '3306',
            'POOL_OPTIONS': {
                'POOL_SIZE': 10, # 最小连接数
                'MAX_OVERFLOW': 10, # 额外增加的连接数
                'RECYCLE': 24 * 60 * 60, # 每个连接最长可以使用多久
                'TIMEOUT': 30,  # 无连接时,最长等待时间
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    model常见字段及参数

    class UserInfo(models.Model):
        # CharField为字符串,max_length为字符串的最大长度,verbose_name字段含义,默认null=False不许为空
        # 一般null和blank结合使用,null指数据库是否为可为空,blank为页面是否可为空
        name = models.CharField(verbose_name='姓名', max_length=10, default='无名氏', null=True, blank=True)
        # db_index表示添加索引,unique唯一约束
        age = models.IntegerField(verbose_name='年龄', db_index=True, unique=True)
        rage = models.BigIntegerField(verbose_name='长整型年龄')
        content = models.TextField(verbose_name='详情')
    
        # auto_now,当插入数据不传该字段时会使用当前时间
        create_data = models.DateField(verbose_name='日期', auto_now=True) # 日期:年月日
        rcreate_data = models.DateTimeField(verbose_name='时间') # 时间:年月日时分秒
        active = models.BooleanField(verbose_name='是否')
        # max_digits总共位数,decimal_places小数点后几位
        salary = models.DecimalField(verbose_name='余额', max_digits=10, decimal_places=2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    表关系

    一对多:

    class UserInfo(models.Model):
        '''用户表'''
        name = models.CharField(max_length=5, verbose_name='员工姓名')
        age = models.IntegerField(verbose_name='年龄')
        # ForeignKey外键,to表示与哪张表关联,to_field表示与哪个字段关联
        # on_delete=models.CASCADE表示级联删除,models.SET_NULL表示设置为null
        # models.SET_DEFAULT表示设置默认值
        # 数据库生成的字段会默认给depart加上_id,depart_id
        depart = models.ForeignKey(verbose_name='部门id',default=1, null=True, blank=True, to='Depart', to_field='id', on_delete=models.SET_DEFAULT)
    class Depart(models.Model):
        '''部门表'''
        name = models.CharField(verbose_name='部门名称')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    多对多:

    class UserInfo(models.Model):
        name = models.CharField(max_length=5, verbose_name='姓名')
    class MusicInfo(models.Model):
        title = models.CharField(max_length=20, verbose_name='音乐标题')
    class UAndM(models.Model):
        nid = models.ForeignKey(to=UserInfo, to_field='id', verbose_name='用户id')
        tid = models.ForeignKey(to=MusicInfo, to_field='id', verbose_name='音乐id')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    orm基本操作

    单表操作
    增:

    def register(request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        dict = {
            'username': username,
            'password': password
        }
        # 方式1
        # 返回值是以UserInfo这个类创建的对象
        # user = models.UserInfo.objects.create(username=username, password=password)
        user = models.UserInfo.objects.create(**dict) # 匹配的参数类型是**kwargs,使用字段传参时,要带上**
        print(user.username)
        print(user.password)
        # 批量插入
        models.User.objects.bulk_create(
            objs=[models.User(name='zs', age=10),models.User(name='ls', age=12)],
            batch_size=2 # 一次提交几条
        )
        # 方式2
        user1 = models.UserInfo(username='zs', password='123')
        user1.save()
        return HttpResponse(user)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    删:

     # 删除
        # 返回值是受影响的行数
        n1 = models.UserInfo.objects.all().delete()
        n2 = models.UserInfo.objects.filter(username='zs').delete()
    
    • 1
    • 2
    • 3
    • 4

    更新:

    # 更新
        # 返回值是受影响的行数
        n3 = models.UserInfo.objects.all().update(password='123')
        n4 = models.UserInfo.objects.filter(username='zs').update(password='123')
    
    • 1
    • 2
    • 3
    • 4

    查询:

        # 查
        list = models.UserInfo.objects.all() # 返回类型是queryset(类似列表),里面存放一个个对象
        # list.query 可以获取sql语句
        for obj in list:
            print(obj.username)
        list2 = models.UserInfo.objects.filter(username='zs') # 返回类型也是queryset
        list3 = models.UserInfo.objects.filter(age__gt=10) # age>10
        # age__gte=10 age>=10
        # age__lt=10   age<10
        # age__lte=10  age<=10
        # age__in=[10,20,30]  age in (10,20,30)
        # username__contains='张'  包含 '张' %张%
        # username__startswith='张' 以 ‘张’ 开头  张%
        list4 = models.UserInfo.objects.filter(username='zs', password='123')  # and
        list5 = models.UserInfo.objects.exclude(username='zs') # username!='zs'
        # 如果查不到数据,返回依旧是queryset,不过里面没对象[]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    	models.UserInfo.objects.filter(username='zs') # queryset[obj,obj]
        models.UserInfo.objects.filter(username='zs').values('username', 'passowrd') # queryset[{},{}]
        models.UserInfo.objects.filter(username='zs').values_list('username', 'passowrd') # queryset[(),()]
    
        user = models.UserInfo.objects.filter(username='zs').first() # 返回值为对象
        flag = models.UserInfo.objects.filter(username='zs').exists() # 返回值为true false 是否存在
    
        users1 = models.UserInfo.objects.all().order_by('id') # 排序 asc
        users2 = models.UserInfo.objects.all().order_by('-id') # 排序 desc
        # order_by('-id', 'age') id desc age asc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    一对多

    def login(request):
        # 一对多查询
        # depart = models.ForeignKey(to='Depart', to_field='id', on_delete=models.CASCADE)
        # 查用户及部门  使用 __
        v = models.User.objects.filter(id=1).first()
        print(type(v.depart)) # 类型为class(为Depart的一个实例对象)  可以使用depart.title获取字段
        v3 = models.User.objects.filter(id__gt=0).select_related('depart')
        for i in v3:
            print(i.name, i.age, i.depart.title)
    
        v1 = models.User.objects.filter(id=1).values('name','age','depart__title') # [{},{}]
        v2 = models.User.objects.filter(id=2).values_list('name','age','depart__title') # [(),()]
       
        return HttpResponse('hh')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    cookie和session

    def login(request):
        res = HttpResponse('hello')
        # path是为了设置那个请求访问时携带上cookie /login   domain为了限制域名
        # 响应头中有setCookie: zs:123,超时时间10s
        # secure=True 只有https请求时才携带cookie
        # httponly=True只允许在http中访问
        res.set_cookie('zs', '123', max_age=10, path='/', domain='baidu.com', secure=False, httponly=False)
        # 默认值 浏览器重新打开 / 当前域名  False False
        return res
    
    def home(request):
        cookies = request.COOKIES # 获取所有的cookie
        print(cookies)
        cookie1 = cookies.get('zs') # 根据键获取值
        return HttpResponse(cookie1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    session配置

    # session配置
    # 存缓存
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 保存会话引擎,缓存.cache,文件.file,数据库.db
    SESSION_CACHE_ALIAS = 'default' # 使用哪个缓存保存,默认使用default,可通过CACHES配置
    # 存文件
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'
    SESSION_FILE_PATH = 'xxx' # 文件路径
    # 存数据库
    SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 必须将app session的注释打开
    
    SESSION_COOKIE_AGE = 1209600 # 两周超时时间
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 关闭 关闭浏览器cookie过期
    SESSION_COOKIE_DOMAIN = None # 域名
    SESSION_COOKIE_PATH = '/' #路径
    SESSION_SAVE_EVERY_REQUEST = True # 设置每次请求都保存session
    SESSION_COOKIE_SECURE = False # 是否https传输cookie
    SESSION_COOKIE_HTTPONLY = True # cookie只支持http传输
    
    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
        },
        'redis': {
            'BACKEND': 'django_redis.cache.RedisCache',
            'LOCATION': 'redis://127.0.0.1:6379/1',
            'OPTIONS': {
                'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            },
        },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    注册app(保存在数据库中需要将注释打开)与添加中间件,django项目默认自带

    在这里插入图片描述

    def login(request):
        request.session['user'] = 'abc' # 设置session
        session = request.session.get('user') # 获取session
    
    • 1
    • 2
    • 3

    demo

    实现登录效果

    def login(request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = models.User.objects.filter(username=username,password=password).first()
        if user != None:
            request.session['user'] = user
            return JsonResponse({'msg': 'login success'})
        else:
            return JsonResponse({'msg': 'login fail'})
    def home(request):
        user = request.session.get('user')
        if user != None:
            return HttpResponse('success')
        else :
            return HttpResponse('fail')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    <script>
        $("#but").click(function(){
            let username = $("#username");
            let password = $("#password");
            $.ajax({
                url: "/login", //请求后端路径
                type: "post", //请求类型
                data: {"username": username.val(), "password": password.val()}, //请求数据(json类型)
                success: function(body){ //回调函数
                    //console.log(typeof body)
                    alert(body.msg)
                }
            });
        })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    settings文件添加该配置

    STATIC_URL = '/static/' # 浏览器可直接访问静态文件
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] # 存放静态文件的公共文件夹
    
    • 1
    • 2
  • 相关阅读:
    VR步进式漫游,轻松构建三维模型,带来展示新形式!
    Python实现PPT演示文稿中视频的添加、替换及提取
    腾讯应用宝上架被驳回
    web 网页开发学习 之 vsc 的快捷方式便捷使用
    C语言之mkdtemp()特定占位符:XXXXXX 用法实例(八十五)
    程序猿成长之路之socket篇-socket通信原理简介
    【vue2高德地图api】高德地图forEach批量添加marker点标记,点击获取item对象『全网最详细』【翻遍csdn总结】
    MogDB逻辑解码与pg_recvlogical
    SQL-方法论
    小流域洪水分析模拟预报设计及代码实现
  • 原文地址:https://blog.csdn.net/qq_58710208/article/details/135637930