Django框架进阶 静态文件配置,request对象方法,pycharm连接数据库,django连接数据库,django orm简介,字段的增删改查,登录功能例子,数据的增删改查
静态文件
什么是静态文件
网站所使用到的提前已经写好了的文件
css
js
第三方的组件
bootstrap
sweetalert
fontawesome
...
网站所用到的html文件统一放到templates文件夹中
针对网站所使用到的静态文件也应该单独找一个文件夹来存储
这个文件夹 默认情况下都叫static
该文件夹需要手动自己创建
并且该文件夹内部通常是以下结构
static
-css
网站所用到的所有的css文件
-js
网站所用到的所有的js文件
-image
网站所用到的所有的图片文件
第三方文件
用户在浏览器窗口之所以输入网址能够拿到对应的资源
是因为后端开设相关的资源
django静态文件配置
django在配置文件中给你暴露了配置文件的配置信息 你只需要按照固定的写法书写
即可暴露对应的静态文件资源
基本配置
STATIC_URL = '/static/' # 访问后端静态资源的接口前缀 默认情况下接口前缀名与静态文件名保持一致 """ <link rel="stylesheet" href="/xxx/bootstrap-3.3.7-dist/css/bootstrap.min.css"> 你要想访问后端的静态资源 你必须以接口前缀开头 后面跟上具体的文件路径 才能访问到对应的资源 当你的接口前缀正确后 会拿着后面的路径依次去下面列表中的每一个文件夹下查找对应的资源 顺序是从上往下依次查找 如果都没有找到才会报错 """ STATICFILES_DIRS = [ # 固定写法 os.path.join(BASE_DIR,'static'), # 这里的static才是你文件夹的路径 os.path.join(BASE_DIR,'static1'), os.path.join(BASE_DIR,'static2'), ]
例:html导入本地bootstrap框架
templates/login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} <link href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet"> <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head> <body> <h1>我是登录页面</h1> </body> </html>
mysite_mysql/urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), ]
mysite_mysql/settings.py
import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'g&x$^psq0a&2tw0tofx($ql%h%&6=91@5ru*%n_#y9szw-5as!' # 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', 'app01.apps.App01Config', ] 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 = 'mysite_mysql.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', '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 = 'mysite_mysql.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # Password validation # https://docs.djangoproject.com/en/1.11/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/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' """ <link rel="stylesheet" href="/xxx/bootstrap-3.3.7-dist/css/bootstrap.min.css"> 你要想访问后端的静态资源 你必须以接口前缀开头 后面跟上具体的文件路径 才能够访问到对应的资源 当你的接口前缀正确之后 会拿着后面的路径依次去下面列表中的每一个文件夹下查找对应的资源 顺序是从上往下依次查找 如果都没有找到才会报错 """ STATICFILES_DIRS = [ # 必须要是这个变量名 os.path.join(BASE_DIR,'static') ]
migrations/views.py
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def login(request): return render(request,'login.html')
此时通过static这个接口前缀,后面接上具体路径,即可访问对应资源
注意:
当你的接口前缀正确之后 会拿着后面的路径依次去下面列表中的每一个文件夹下查找对应的资源
顺序是从上往下依次查找 如果都没有找到才会报错
例:把接口前缀改为xxx,静态文件路径添加新的路径,优先从static文件开始向下查找
static/a.txt
this is static's a.txt
static1/a.txt
this is static1's a.txt
注意:templates下的login.html接口前缀也要改为xxx
输入对应url,查看结果为第一个文件
如何解决动态绑定的问题(******)
当中的static为固定格式,不要变更
{% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
变更接口前缀为'/yyy/'
静态文件的第二种配置方法
关于静态文件夹static既可以在全局创建,也可以在每一个应用创建
"""静态文件配置""" # 1.配置文件中直接指定查找路径 方式一 STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static1'), os.path.join(BASE_DIR,'static2'), os.path.join(BASE_DIR,'static3'), os.path.join(BASE_DIR,'static4'), ] # 2.直接利用模版语法 方式二 {% load staticfiles %} <script src="{% static 'js/go.js' %}"></script>
# 配置文件中配置
STATIC_URL = '/static/'
form表单
form表单默认是以get请求提交数据的
http://127.0.0.1:8000/login/?username=ldc&password=123
action
1.不写 默认朝当前地址提交数据
2.全路径
3.后缀(/index)
提交post请求的时候 需要先去配置文件中注释掉一行
templates/login.html中body修改为 (先不修改上图配置文件)
<body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">登录</h2> <form action="" method="post"> <!--把form表单从get请求方式变为post--> <p>username:<input type="text" name="username" class="form-control"></p> <!-- form-control占满一行 --> <p>password:<input type="text" name="password" class="form-control"></p> <input type="submit" class="btn btn-success"> </form> </div> </div> </div> </body>
此时点击提交按钮会报错
需要先去配置文件中注释掉一行
视图函数应该做到针对不同的请求 做出不同的处理逻辑
eg:
get请求来 应该只需要返回一个html文件
post请求来 应该获取用户提交的数据 然后做进一步处理
你必须要能够判断出当前请求到底是什么请求
request对象
获取前端请求方式
request.method #结果是一个大写的字符串 GET/POST request.POST # 获取post请求提交的数据 类似是一个大字典 # <QueryDict: {'username': ['admin', 'jason'], 'password': ['123']}> request.POST.get() #只会取列表最后一个元素 request.POST.getlist() #取出整个列表 request.GET #获取符合get请求携带数据格式的数据 url?xxx=yyy&ooo=lll # <QueryDict: {'username': ['admin', 'jason'], 'password': ['123']}> request.GET.get() #只会取列表最后一个元素 request.GET.getlist() #取出整个列表
通常情况下针对不同的请求应该做不同的处理 而一般情况下get请求次数要远远低于post请求
所以我们应该针对非get请求作出逻辑判断 将get请求直接写在函数体内而不做判断
def login(request): # 要给用户返回一个登陆页面 # print('我被触发了') # 获取前端请求方式 # if request.method == 'GET': # # get逻辑 # return render(request, 'login.html') # elif request.method == 'POST': # # post逻辑 # # print(request.method,type(request.method)) # GET <class 'str'> POST <class 'str'> # # 获取数据 之后... # return HttpResponse('收到了你的数据 马上处理') """为了减少代码的层级:一般情况下视图函数处理get请求较多 所以可以直接再函数体内先写get请求对应的逻辑 将其他请求利用request.method做出区分 """ if request.method == 'POST': return HttpResponse('收到了') return render(request,'login.html')
pycharm链接MySQL
点击Database按钮
选择要连接的数据库
如果无法连接,选择驱动版本
注意:添加表示注意要点击DB按钮,才会变更表内容
django链接MySQL(******)
需要你自己提前创建好对应的库
1.先去配置文件中配置相关参数
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库类别 'NAME': 'test', # 库的名字 'HOST': '127.0.0.1', 'PORT': 3306, 'USER':'root', 'PASSWORD': '', 'CHARSET':'utf8' # 在django中不要设定 autocommit=True } }
注意:此时运行django项目报错,因为pycharm默认使用MySQLdb模块,但是对于1.x版本的django框架不兼容,所以必须把默认的MySQLdb模块改为pymysql模块
2.在项目名或者应用名下面的__init__文件中告诉django使用pymysql链接数据库而不是用默认的mysqldb
import pymysql pymysql.install_as_MySQLdb()
django orm简介
django orm不会帮你创建库 只能帮你自动创建表
orm对象关系映射
类 表
对象 记录
属性 字段值
作用:能够让一个不会数据库操作的小白也能够通过Python面向对象语法 句点符来简单快捷的操作数据
首先需要先去对应的应用下的models.py中书写你的模型类
在models.py中
from django.db import models # Create your models here. class User(models.Model): # id int primary key auto_increment id = models.AutoField(primary_key=True) # name varchar(32) 注意必须加入max_lengten参数 name = models.CharField(max_length=32) # password int password = models.IntegerField()
*************************数据库迁移(同步)命令************************
1.python3 manage.py makemigrations # 仅仅是将你对数据库的改动记录到某个小本本上(migrations文件夹) 2.python3 manage.py migrate # 将改动真正的同步到数据库中
"""
上面两个命令永远是成对出现的 只要你执行了1 就必须要执行2
"""
***********只要你动了models.py跟数据库相关的代码 你就必须要重新执行上面的两条命令来保证数据库与models.py一致***********
注:在cmd控制台执行了第一条命令后,会在migrations文件夹中生成 0001_initial.py文件,但数据库没有生成
# -*- coding: utf-8 -*- # Generated by Django 1.11.11 on 2020-01-05 09:49 from __future__ import unicode_literals from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='User', fields=[ ('id', models.AutoField(primary_key=True, serialize=False)), ('name', models.CharField(max_length=32)), ('password', models.IntegerField()), ], ), ]
控制台命令如下
打开Navicat可以看到,表已经创建
另外,django支持多app开放,防止冲突问题
注意:另外如果创建表示没有添加索引,django orm会自动添加索引
class Book(models.Model): # 当你没有指定主键的时候 django orm会自动帮你创建一个名为id的主键字段 # 一旦监测到你自己创建了主键字段 那么就不会再帮你创建 name = models.CharField(max_length=32)
此次使用pycharm简写快捷方式
输入简写 makemigrations
输入migrate创建库
自动创建的id为主键
字段的增删改查
字段的增
1.要么给该字段设置默认值
2.要么运行该字段可以为空
class User(models.Model): # id int primary key auto_increment id = models.AutoField(primary_key=True) # name varchar(32) 注意必须加入max_lengten参数 name = models.CharField(max_length=32) # password int password = models.IntegerField() # 新增一个邮箱字段 # email varchar(255) email = models.EmailField(default='123@qq.com') # hobby字段可以为空 hobby = models.CharField(null=True,max_length=32)
字段的查
...
字段的改
修改models代码 之后执行数据库迁移命令即可
字段的删
只要注释掉对应的字段 执行数据库迁移命令就会将对应的字段及数据信息全部删除(慎用)
数据的增删改查
查
1.filter()
from app01 import models res = models.User.objects.filter(username='jason') # select * from user where username='jason' # 返回的结果是一个列表 支持索引取值但是不支持负数并且不推荐使用 推荐你使用它给你封装好的方法 user_obj = res.first() # filter方法条件不存在的时候 不会报错返回的是一个空列表 """ filter括号内直接放多个关键字参数 并且多个关键字参数之间是and关系 res = models.User.objects.filter(username='jason',password='123') # select * from user where username='jason' and password='123'; """
例:
app01/views.py
from django.shortcuts import render,HttpResponse,redirect from app01 import models # Create your views here. def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 查询数据库 # User为表名 res = models.User.objects.filter(name=username) #该方法返回的结构你可以看成是一个列表套对象的形式 # print(res) # <QuerySet [<User: User object>]> print(res) # user类中添加__str__方法 返回self.name < QuerySet[ < User: jason >] > # user_obj = res[0] # QuerySet支持索引取值但是不支持负数 并且也不推荐你直接索引取值 user_obj = res.first() # 推荐使用此方法取对象 print(user_obj.name,user_obj.password) # jason 123 return HttpResponse('收到了') return render(request,'login.html')
app01/models.py(在User类中添加__str__方法, 打印是显示类名)
from django.db import models # Create your models here. class User(models.Model): # id int primary key auto_increment id = models.AutoField(primary_key=True) # name varchar(32) 注意必须加入max_lengten参数 name = models.CharField(max_length=32) # password int password = models.IntegerField() def __str__(self): # 注意次代码和数据库没有关系,写完后没必要对数据库进行迁移 return self.name class Book(models.Model): # 当你没有指定主键的时候 django orm会自动帮你创建一个名为id的主键字段 # 一旦监测到你自己创建了主键字段 那么就不会再帮你创建 name = models.CharField(max_length=32)
注意:此处修改为类方法,和数据库没有任何关系,写完后没必要对数据库进行迁移
增
1.create()
user_obj = models.User.objects.create(name=username,password=password) print(user_obj,user_obj.name) # 该方法有返回值 返回值就是当前被创建的对象本身
2.对象的绑定方法
# 方式2 # 1 先生成一个User对象 user_obj = models.User(name=username,password=password) # 2 调用对象的绑定方法 user_obj.save()
删
用户点击谁 你的后端就应该删除
后端如何获取用户想要删除的数据id?
models.User.objects.filter(id=delete_id).delete() # 将filter过滤出来的数据全部删除 批量删除
例:
通过html中添加a标签,删除按钮
注意:通过跳转链接中给出删除内容的id号,以便删除方法获取id
<a href="/delete_user/?delete_id={{ user_obj.id }}" class="btn btn-danger btn-xs">删除</a>
urls.py中添加对应方法
views.py中增加删除方法
def del_user(request): #如何获取用户想要删除的数据id delete_id = request.GET.get('delete_id') # 通过给出链接获得id # 直接根据id删除数据 models.User.objects.filter(id=delete_id).delete() #将filter过滤出来的数据全部删除 # 重定向到展示页 return redirect('/home/')
改
如何获取用户想要修改的数据id
根据数据id获取数据并且展示到前端页面供用户查看
# 方式1(推荐) 批量更新 models.User.objects.filter(id=edit_id).update(name=username,password=password) # 方式2(不推荐,会把所有数据都改一遍,效率极低) # 1 先获取数据对象 edit_obj = models.User.objects.filter(id=edit_id).first() # 2 再修改对象属性 edit_obj.name = username edit_obj.password = password # 3 调用对象的绑定方法保存 edit_obj.save()
用户数据注册,登录,编辑,删除示例
app01/__init__.py
import pymysql pymysql.install_as_MySQLdb()
app01/apps.py
from django.apps import AppConfig class App01Config(AppConfig): name = 'app01'
app01/models.py
from django.db import models # Create your models here. class User(models.Model): # id int primary key auto_increment id = models.AutoField(primary_key=True) # name varchar(32) 注意必须加入max_lengten参数 name = models.CharField(max_length=32) # password int password = models.CharField(max_length=32) def __str__(self): # 注意此代码和数据库没有关系,写完后没必要对数据库进行迁移 return self.name class Book(models.Model): # 当你没有指定主键的时候 django orm会自动帮你创建一个名为id的主键字段 # 一旦监测到你自己创建了主键字段 那么就不会再帮你创建 name = models.CharField(max_length=32)
app01/views.py
from django.shortcuts import render,HttpResponse,redirect from app01 import models # Create your views here. def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 查询数据库 # User为表名 res = models.User.objects.filter(name=username) #该方法返回的结构你可以看成是一个列表套对象的形式 # print(res) # <QuerySet [<User: User object>]> # print(res) # user类中添加__str__方法 返回self.name < QuerySet[ < User: jason >] > # user_obj = res[0] # QuerySet支持索引取值但是不支持负数 并且也不推荐你直接索引取值 if res: user_obj = res.first() # 推荐使用此方法取对象 if user_obj.password == password: # print(user_obj.name,user_obj.password) # jason 123 return HttpResponse('登录成功') else: return HttpResponse('密码错误') return HttpResponse('用户名不存在') return render(request,'login.html') def reg(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 直接朝数据库中添加数据 # 方式1 # user_obj = models.User.objects.create(name=username,password=password) # print(user_obj,user_obj.name) # 方式2 user_obj = models.User(name=username,password=password) user_obj.save() return render(request,'register.html') def home(request): # 获取User中的所有数据 # res = models.User.objects.filter() # print(res) user_queryset = models.User.objects.all() # print(res) return render(request,'home.html',{'res':user_queryset}) def del_user(request): #如何获取用户想要删除的数据id delete_id = request.GET.get('delete_id') # 通过给出链接获得id # 直接根据id删除数据 models.User.objects.filter(id=delete_id).delete() #将filter过滤出来的数据全部删除 # 重定向到展示页 return redirect('/home/') def edit_user(request): # 获取用户想要修改的数据id值 edit_id = request.GET.get('edit_id') if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') #修改数据 models.User.objects.filter(id=edit_id).update(name=username,password=password) #再次跳转到数据展示页 return redirect('/home/') # 根据id获取数据对象 并且展示到html页面上 edit_obj = models.User.objects.filter(id=edit_id).first() return render(request,'edit_user.html',{'edit_obj':edit_obj})
mysite_mysql/settings.py
""" Django settings for mysite_mysql project. Generated by 'django-admin startproject' using Django 1.11.11. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'g&x$^psq0a&2tw0tofx($ql%h%&6=91@5ru*%n_#y9szw-5as!' # 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', 'app01.apps.App01Config', ] 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 = 'mysite_mysql.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', '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 = 'mysite_mysql.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库类别 'NAME': 'test', # 库的名字 'HOST': '127.0.0.1', 'PORT': 3306, 'USER':'root', 'PASSWORD': '', 'CHARSET':'utf8' # 在django中不要设定 autocommit=True } } # Password validation # https://docs.djangoproject.com/en/1.11/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/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' """ <link rel="stylesheet" href="/xxx/bootstrap-3.3.7-dist/css/bootstrap.min.css"> 你要想访问后端的静态资源 你必须以接口前缀开头 后面跟上具体的文件路径 才能够访问到对应的资源 当你的接口前缀正确之后 会拿着后面的路径依次去下面列表中的每一个文件夹下查找对应的资源 顺序是从上往下依次查找 如果都没有找到才会报错 """ STATICFILES_DIRS = [ # 必须要是这个变量名 os.path.join(BASE_DIR,'static'), os.path.join(BASE_DIR,'static1') ]
mysite_mysql/urls.py
"""mysite_mysql URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.login), url(r'^reg/', views.reg), # 用户展示页 url(r'^home/', views.home), # 删除功能 url(r'^delete_user/', views.del_user), # 编辑功能 url(r'^edit_user/', views.edit_user), ]
templates/edit_user.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {# <link href="/xxx/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="/xxx/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>#} {% load static %} <link href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}" rel="stylesheet"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">编辑</h2> <form action="" method="post"> <!--把form表单从get请求方式变为post--> <p>username:<input type="text" name="username" class="form-control" value="{{ edit_obj.name }}"></p> {# <p>username:<input type="text" name="username" class="form-control"></p>#} <p>password:<input type="text" name="password" class="form-control" value="{{ edit_obj.password }}"></p> {# <p>hobby:#} {# bbb<input type="checkbox" name="hobby" value="bbb">#} {# aaa<input type="checkbox" name="hobby" value="aaa">#} {# ccc<input type="checkbox" name="hobby" value="ccc">#} {# </p>#} <input type="submit" class="btn btn-warning pull-right"> </form> </div> </div> </div> </body> </html>
templates/home.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {% load static %} <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">数据展示</h1> <table class="table table-striped table-hover"> <thead> <tr> <th>id</th> <th>name</th> <th>password</th> <th>operation</th> </tr> </thead> <tbody> {% for user_obj in res %} <tr> <td>{{ user_obj.id }}</td> <td>{{ user_obj.name }}</td> <td>{{ user_obj.password }}</td> <td> <a href="/edit_user/?edit_id={{ user_obj.id }}" class="btn btn-primary btn-xs">编辑</a> <a href="/delete_user/?delete_id={{ user_obj.id }}" class="btn btn-danger btn-xs">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
templates/login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {# <link href="/xxx/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="/xxx/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>#} {% load static %} <link href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}" rel="stylesheet"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">登录</h2> <form action="" method="post"> <!--把form表单从get请求方式变为post--> <p>username:<input type="text" name="username" class="form-control"></p> {# <p>username:<input type="text" name="username" class="form-control"></p>#} <p>password:<input type="text" name="password" class="form-control"></p> {# <p>hobby:#} {# bbb<input type="checkbox" name="hobby" value="bbb">#} {# aaa<input type="checkbox" name="hobby" value="aaa">#} {# ccc<input type="checkbox" name="hobby" value="ccc">#} {# </p>#} <input type="submit" class="btn btn-success"> </form> </div> </div> </div> </body> </html>
templates/register.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {# <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>#} {# <link href="/xxx/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">#} {# <script src="/xxx/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>#} {% load static %} <link href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}" rel="stylesheet"> <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">注册</h2> <form action="" method="post"> <!--把form表单从get请求方式变为post--> <p>username:<input type="text" name="username" class="form-control"></p> {# <p>username:<input type="text" name="username" class="form-control"></p>#} <p>password:<input type="text" name="password" class="form-control"></p> {# <p>hobby:#} {# bbb<input type="checkbox" name="hobby" value="bbb">#} {# aaa<input type="checkbox" name="hobby" value="aaa">#} {# ccc<input type="checkbox" name="hobby" value="ccc">#} {# </p>#} <input type="submit" class="btn btn-primary"> </form> </div> </div> </div> </body> </html>