一、django简介
Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的软件设计模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。
Django是一个基于MVC构造的框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式。它们各自的职责如下:
模型(Model),即数据存取层
处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。
模板(Template),即表现层
处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。
视图(View),即业务逻辑层
存取模型及调取恰当模板的相关逻辑。模型与模板之间的桥梁。
django基本结构:
myiste # 总程序名 UserManageSys # 用户APP migrations # 数据库文件夹 0001——initial.py # 数据库 __init__.py __init__.py admin.py # 后台,可以用很少量的代码就拥有一个强大的后台。 apps.py models.py # 与数据库操作相关,存入或读取数据时用到这个 tests.py views.py # 处理用户发出的请求,从urls.py中对应过来, 通过渲染templates中的网页可以将显示内容比如登陆后的用户名,用户请求的数据,输出到网页。 mysite # 配置文件 __init__.py settings.py # Django 的设置,配置文件,比如 DEBUG 的开关,静态文件的位置等 urls.py # 网址入口,关联到对应的views.py中的一个函数(或者generic类),访问网址就对应一个函数。 wsgi.py # wsgi有多重一种uwsgi和wsgi,你用那种wsgi来运行Django, 一般不用改只有你用到的时候在改 static # 一些js,css,images.静态文件夹 assets # 第三方插件等 css # 样式 images # 存放图片 js # javaScripy templates # templates中的Html模板, add_user.html # 添加用户 base.html # 基础模板 del_user.html # 删除用户 index.html # 主页 login.html # 登录页面 register.html # 注册页面 db.sqlite3 # 数据库 manage.py # 启动整个项目文件 readme # 帮助文档
二、安装django
1.window上使用pip安装 pip install django 2.linux下使用pip安装 yum install python-pip pip install django 3.检查是否安装成功 >>> import django >>> django.VERSION
三、django基本命令
1.创建django命令 django-admin.py startproject mysite(程序名) 2.创建django的app python manage.py startapp cmdb(app的名字) 或 django-admin.py startapp cmdb(app的名字) 3.同步数据库 python manage.py syncdb 注意:Django 1.7.1及以上的版本需要用以下命令 python manage.py makemigrations python manage.py migrate 4.调试模式 python manage.py runserver 8001 # 监听所有可用 ip (电脑可能有一个或多个内网ip,一个或多个外网ip,即有多个ip地址) python manage.py runserver 0.0.0.0:8000 5.清除数据库 python manage.py flush 6.创建超级管理员 python manage.py createsuperuser 按照提示就ok 7.修改管理员密码 python manage.py changepassword username(你当时设定的用户名) 8.导入和导出数据 python manage.py dumpdata appname > appname.json python manage.py loaddata appname.json 9.进入数据库 python manage.py dbshell 10.更多命令 python manage.py
四、创建第一个Django程序
1、project\app
Project和App概念
Project是一个大的工程,
下面有很多功能:(一个Project有多个App,其实他就是对你大的工程的一个分类)
例如一个运维平台是一个工程,那么他的app就是CMDB,监控系统,OA系统,
2.生成数据库 创建超级管理员用户
注:此步骤是在pycharm的终端里使用命令实现的
1.同步数据库 python manage.py makemigrations python manage.py migrate 2.创建超级管理员 python manage.py createsuperuser 3.运行django python manage.py runserver 8000
登录页面:
浏览器访问:
http://127.0.0.1:8000/admin/
3.路由
1.首先在mysite文件夹下(不是app目录,千万别写错)的urls.py填写路由规则
from django.conf.urls import url from django.contrib import admin # 导入app下的view函数 from mysite import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 当用户访问http://127.0.0.1:端口号的时候之间交给myiste下面的views里的index函数来处理 url(r'^$', views.index), ]
4.views函数
1.在myiste(app)下面的views里写一个index函数
# Django 在返回的时候需要一层封装,需要导入HttpResponse from django.shortcuts import render,HttpResponse # Create your views here. def index(request): #使用HttpRespons 封装返回信息 return HttpResponse('hello world!!!
')
django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。
2.如果要返回html页面
1.在templates里创建index.html页面 内容: "en"> "UTF-8">第一个django程序 Hello world!!
2.修改mysite里的views.py的index函数 from django.shortcuts import render,HttpResponse # Create your views here. def index(request): # return HttpResponse('hello world!!!
') return render(request,'index.html') #找到index.html #读取index.html返回给用户
当以上步骤都完成之后
python manage.py runserver 8000
使用浏览器访问:
http://127.0.0.1:8000(默认为8000端口)
五、django路由系统
在Django的urls中我们可以根据一个URL对应一个函数名来定义路由规则如下:
每一个urls对应一个views里的函数
1.基本的urls对应
from django.conf.urls import url from django.contrib import admin from UserManageSys.views import index, login, register, add_user, del_user urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/$', index), url(r'^$', login), url(r'^login/$', login), url(r'^register/$', register), url(r'^user/add/$', add_user), url(r'^user/del/$', del_user), ]
2.基于app的路由
根据app对路由规则进行一次分类
当app的urls很多的时候,那么就不能再工程的urls下面去设置
应该这样设置:
1.首先在mysite下面的urls这样设置
# 导入include from django.conf.urls import url,include from django.contrib import admin # 导入app下的view函数 from mysite import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 使用myister的urls规则 url(r'^myister/',include('mysite/urls')) ]
2.在mysite下面创建一个urls.py
内容:
from django.conf.urls import url from django.contrib import admin from UserManageSys.views import index, login, register, add_user, del_user urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/$', index), url(r'^$', login), url(r'^login/$', login), url(r'^register/$', register), url(r'^user/add/$', add_user), url(r'^user/del/$', del_user), ]
3.在usermanagesys下面的views里创建上面urls对应的函数
from django.shortcuts import render, redirect from django.http import Http404, HttpResponse from UserManageSys import models # Create your views here. def index(request): user_list_db = models.UserInfo.objects.all() return render(request, 'index.html', {'li': user_list_db}) def login(request): if request.method == 'POST': username = request.POST.get('username', None) password = request.POST.get('password', None) user_exist = models.UserInfo.objects.filter(username=username, password=password).count() if user_exist: request.session['username'] = username return redirect('/index/') else: return render(request, 'login.html') return render(request, 'login.html', {'code': 0}) def register(request): if request.method == 'POST': u = request.POST.get('username', None) p = request.POST.get('password', None) e = request.POST.get('email', None) already_user = models.UserInfo.objects.filter(username=u).count() print(already_user) if already_user: return render(request, 'register.html') else: models.UserInfo.objects.create(username=u, password=p, email=e) return render(request, 'register.html') return render(request, 'register.html') def add_user(request): if request.method == 'POST': u = request.POST.get('username', None) p = request.POST.get('password', None) e = request.POST.get('email', None) print(u, p, e) user_info = {'username': u, 'email': e} already_user = models.UserInfo.objects.filter(username=u).count() print(already_user) if already_user: data = {'status': 1, 'result': '此用户已经存在!', 'data': user_info} return render(request, 'add_user.html', data) else: models.UserInfo.objects.create(username=u, password=p, email=e) data = {'status': 0, 'result': '用户添加成功!', 'data': user_info} return render(request, 'add_user.html', data) return render(request, 'add_user.html') def del_user(request): if request.method == 'POST': u = request.POST.get('username', None) p = request.POST.get('password', None) e = request.POST.get('email', None) print(u, p, e) user_info = {'username': u, 'email': e} already_user = models.UserInfo.objects.filter(username=u).count() print(already_user) if already_user: models.UserInfo.objects.filter(username=u, password=p, email=e).delete() data = {'status': 1, 'result': '用户删除成功!', 'data': user_info} return render(request, 'del_user.html', data) else: data = {'status': 0, 'result': '用户不存在成功!', 'data': user_info} return render(request, 'del_user.html', data) return render(request, 'del_user.html')
4.访问:
http://127.0.0.1:8000 # 登录页面 http://127.0.0.1:8000/register/ # 注册页面 http://127.0.0.1:8000/index/ # 主页面 http://127.0.0.1:8000/user/add/ # 添加用户页面 http://127.0.0.1:8000/user/del/ # 删除用户页面
3.动态路由(传一个参数)
比如分页:当urls大量过多的时候比如几百个的时候,那么肯定不会去写几百个路由规则
所有这个时候就需要动态urls,使用正则表达式来完成
1.在usermanagesys下面的urls写入以下内容:
from django.conf.urls import url,include from django.contrib import admin # 导入app下的view函数 from . import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/(\d+)$', views.book), // 正则匹配 ]
2.在usermanagesys下面的views写入以下内容:
from django.shortcuts import render,HttpResponse # Create your views here. def book(request,num): print(num) return HttpResponse(num) 当用户访问http://127.0.0.1:8000/usermanagesys/book/数字的时候 django会在自动把参数传给views里的book函数
3.测试访问:
http://127.0.0.1:8000/usermanagesys/book/2 显示2 http://127.0.0.1:8000/usermanagesys/book/1 显示1
4.动态路由(传多个参数)
多个参数它是已/来分割的
来一个url的加法
1.在usermanagesys下面的urls写入以下内容: from django.conf.urls import url,include from django.contrib import admin #导入app下的view函数 from . import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/(\d+)/(\d+)$', views.book), ] 2.在helloapp下面的views写入以下内容: def book(request,num1,num2): print(num1,num2) num = int(num1) + int(num2) return HttpResponse(num) 3.测试访问: http://127.0.0.1:8000/usermanagesys/book/2/1 显示3 http://127.0.0.1:8000/usermanagesys/book/2/10 显示12
他的顺序是:正序的,你先给他传那个值,第一个参数就是那个
5.动态的路由(Key:value的形式)
1.在usermanagesys下面的urls写入以下内容: from django.conf.urls import url,include from django.contrib import admin #导入app下的view函数 from . import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/(?P\d+)/(?P ', views.book), 这里?p\d+)$ 这里的v1就是key,vlaue就是传进去的值, ] 2.在usermanagesys下面的views写入以下内容: from django.shortcuts import render,HttpResponse # Create your views here. def book(request,k1,k2): print(k1,k2) return HttpResponse(k1+k2)
这样我们就不必按照顺序去取了,可以通过key,value的方式来取传进来的值
注:可以根据传来的值来进行判断返回给用户指定的url,过程略。
6.基于反射的动态路由
仅仅是通过反射来实现的,通过文件找到里面的函数然后执行!
但是在Django中不建议使用此方法。因为不同的WEB框架建议你使用不同的方式,
Django就不建议使用反射
#/usr/bin/env python #-*- coding:utf-8 -*- from django.shortcuts import render #Django 在返回的时候需要一层封装,需要导入HttpResponse from django.shortcuts import HttpResponse # Create your views here. def home(request): #他内部做了几步操作 #找到home.html #读取home.html返回给用户 return render(request,'home.html')
模板
上面已经可以正常的返回html了,我们要给他使用模板语言进行渲染怎么渲染呢?
#/usr/bin/env python #-*- coding:utf-8 -*- from django.shortcuts import render #Django 在返回的时候需要一层封装,需要导入HttpResponse from django.shortcuts import HttpResponse # Create your views here. def home(request): #他内部做了几步操作 #找到home.html #读取home.html返回给用户 #定义一个字典然后传给render dic = {'name':'rain','age':'21','user_list':['rain','beautiful'],} return render(request,'home.html',dic)
html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板渲染title>
head>
<body>
<div style="background-color:red ;height: 100px">
{{ name }} // 变量
{{ age }}
div>
<div style="background-color:blue ;height: 100px">
<ul>
{% for iterm in user_list %} // 循环{% 语句 %}
<li> {{ iterm }} li>
{% endfor %} // 循环结束符
ul>
div>
<div style="background-color:green ;height: 100px">
{% if name == 'rain' %}
<div style="background-color:red">hello raindiv>
{% else %}
<div style="background-color:blue">raindiv>
{% endif %}
div>
body>
html>
-
- {{ item }}
- {% for item in item_list %} {{ item }} {% endfor %}
forloop.counter
forloop.first
forloop.last - {% if ordered_warranty %} {% else %} {% endif %}
- 母板:{% block title %}{% endblock %}
子板:{% extends "base.html" %}
{% block title %}{% endblock %} - 帮助方法:
{{ item.event_start|date:"Y-m-d H:i:s"}}
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}
纵然上面的方法不少但是还是不够,所以就出现了自定义方法。
2、自定义模板语言
2.1、在app中创建templatetags模块
2.2、创建任意 .py 文件,如:html_Template_Langureg.py
#!/usr/bin/env python #coding:utf-8 from django import template from django.utils.safestring import mark_safe from django.template.base import resolve_variable, Node, TemplateSyntaxError register = template.Library() @register.simple_tag def my_simple_time(v1,v2,v3): return v1 + v2 + v3 @register.simple_tag def my_input(id,arg): result = "" %(id,arg,) return mark_safe(result)
2.3、在使用自定义simple_tag的html文件中最顶部导入之前创建的 xx.py(html_Template_Langureg.py) 文件名
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板渲染title>
head>
<body>
<div style="background-color:red ;height: 100px">
{{ name }} // 变量
{{ age }}
div>
<div style="background-color:blue ;height: 100px">
<ul>
{% for iterm in user_list %} // 循环{% 语句 %}
<li> {{ iterm }} li>
{% endfor %} // 循环结束符
ul>
div>
<div style="background-color:green ;height: 100px">
{% if name == 'rain' %}
<div style="background-color:red">hello raindiv>
{% else %}
<div style="background-color:blue">raindiv>
{% endif %}
div>
body>
html>
2.4、在settings中配置当前app,不然django无法找到自定义的simple_tag
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
]
2.5、测试使用
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板渲染title>
head>
<body>
<div style="background-color:red ;height: 100px">
{{ name }} // 变量
{{ age }}
div>
<div style="background-color:blue ;height: 100px">
<ul>
{% for iterm in user_list %} // 循环{% 语句 %}
<li> {{ iterm }} li>
{% endfor %} // 循环结束符
ul>
div>
<div style="background-color:green ;height: 100px">
{% if name == 'rain' %}
<div style="background-color:red">hello raindiv>
{% else %}
<div style="background-color:blue">raindiv>
{% endif %}
div>
<div>
{% my_simple_time 1 2 3 %} // 传替换参数 1 2 3
{% my_input 'id_name' 'arg_value' %}
div>
body>
html>
3、母板
上面、左侧的红色框体都没有变,变得是中间的内容是怎么实现的呢?就是通过母版来实现的
我们创建一个母版 - 子版去继承母版就可以了,子版里是变化的内容即可。
在templates目录下面创建一个master目录(统一用他吧),然后在master目录下创建一个master_templates.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
<style>
.header{
height: 48px;
background-color: red;
}
.body{
background-color: #dddddd;
}
.body .menu{
background-color: green;
float: left;
width: 20%;
}
.body .content{
background-color: aquamarine;
float: left;
width:70%;
}
style>
head>
<body>
<div class="header"><h1>LOGOh1>div>
<div class="body">
<div class="menu">左侧菜单div>
<div class="content">
{# 可变的子版内容,这个content和class content无关 #}
{% block content %} {% endblock %}
div>
div>
body>
html>
然后在看下子版的内容
{% extends 'master/master_templates.html' %} {% block content %} <h1>测试继承母版h1> {% endblock %}
extends 集成那个模板 ,在加一个block content 来书写变化的内容。
3.2、增加URL路由和函数
def son(request): return render(request,'son_html.html')
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^home/', views.home), url(r'^son/', views.son), ]
母版最多允许出现一个母版(可以写多个,但是建议不要写多个)
4、导入标签
创建一个include目录(名字可以随意定义),下面创建需要的html文件,里面写上要导入的内容
"en"> "UTF-8">输入组合
"text"/> "text"/> "text"/> "text"/> "text"/>
然后在html中导入
{% extends 'master/master_templates.html' %} {% block content %}测试模板
{% include 'include/simple_input.html' %} {% endblock %}
以后比如某些公共的模块可以使用include的方式导入!很方便
Django静态文件配置
把所有的静态都放在static目录下,比如:css、js、imgs、等
相关的css文件在css文件夹中创建
然后在html里引用:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="stylesheet" href="/static/css/common.css">
{# 然后在模板里,我们也会写一个block,如果子版里有需要使用自己的css样式可以自己定义#}
{% block css %} {% endblock %}
head>
<body>
<div class="header"><h1>LOGOh1>div>
<div class="body">
<div class="menu">左侧菜单div>
<div class="content">
{#可变的子版内容,这个content和class content无关#}
{% block content %} {% endblock %}
div>
div>
{# 公共的js写到母版中,如果某一个模板里使用自己的js,在写一个block即可#}
{% block js %} {% endblock %}
body>
html>
注:在模板里引入了相应的css和js之后,子版里是默认继承的。如果某个子版想独立使用它自己的js,我们可以通过:{% block css %} {% endblock %} || {% block js %} {% endblock %}来定义!
2、配置引入static目录,在settings里,否则无法使用static目录下的静态文件,因为他找不到路径的需要告诉django
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
用户登录实例
1、创建两个html,login.html & index.html
login.html(不要忘记导入bootstrap)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.4-dist/css/bootstrap.min.css">
head>
<body>
<div style="width: 200px;">
<form class="form-horizontal">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Emaillabel>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3" placeholder="Email">
div>
div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Passwordlabel>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3" placeholder="Password">
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign inbutton>
div>
div>
form>
div>
<script src="/static/js/jquery-2.2.1.min.js">script>
<script src="/static/plugins/bootstrap-3.3.4-dist/js/bootstrap.min.js">script>
body>
html>
1.2、创建URL路由规则和函数
url
url(r'^login/', views.login),
函数
def login(request):
return render(request,'login.html')
2.2、提交到哪里在哪里定义?
<form class="form-horizontal" action="/login/" method="post">
提交到在form表单中的action里定义:这里的/login/是URL,当咱们访问URL的时候回给执行咱们定义的函数,前面和后面都要有/ 并且使用方法为post
访问的时候是使用的GET方式,当提交的时候使用的是post请求!我们就可以判断!
def login(request): #如果是GET请求 #如果是POST,检查用户输入 #print request.method 来查看用户是通过什么方式请求的 #还有个问题:当你POST的时候,会出现问题,现在临时解决方法是:在seetings里注释掉 ''' MIDDLEWARE_CLASSES = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 注释掉这一行 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ''' if request.method == 'POST': input_email = request.POST['email'] input_pwd = request.POST['pwd'] if input_email == '[email protected]' and input_pwd == '123': #当登录成功后给它跳转,这里需要一个模块from django.shortcuts import redirect #成功后跳转到指定网址 return redirect('http://www.etiantian.org') else: #如果没有成功,需要在页面告诉用户用户名和密码错误. return render(request,'login.html',{'status':'用户名或密码错误'}) #通过模板语言,来在login.html中添加一个status的替换告诉用户{{ status }} return render(request,'login.html')
然后看下html文件
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.4-dist/css/bootstrap.min.css">
head>
<body>
<div style="width: 200px;">
<form class="form-horizontal" action="/login/" method="post">
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Emaillabel>
<div class="col-sm-10">
<input type="email" class="form-control" name="email" placeholder="Email">
div>
div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Passwordlabel>
<div class="col-sm-10">
<input type="password" class="form-control" name="pwd" placeholder="Password">
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign inbutton>
<span style="color: red;">{{ status }}span>
div>
div>
form>
div>
<script src="/static/js/jquery-2.2.1.min.js">script>
<script src="/static/plugins/bootstrap-3.3.4-dist/js/bootstrap.min.js">script>
body>
html>
效果在登录错误的时候(登录成功会跳转)
如果想跳转到自己的页面可以这么写:
def login(request): #如果是GET请求 #如果是POST,检查用户输入 #print request.method 来查看用户是通过什么方式请求的 #还有个问题:当你POST的时候,会出现问题,现在临时解决方法是:在seetings里注释掉 ''' MIDDLEWARE_CLASSES = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 注释掉这一行 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ''' if request.method == 'POST': input_email = request.POST['email'] input_pwd = request.POST['pwd'] if input_email == '[email protected]' and input_pwd == '123': #当登录成功后给它跳转,这里需要一个模块from django.shortcuts import redirect #成功后跳转到指定网址 return redirect('/son/') else: #如果没有成功,需要在页面告诉用户用户名和密码错误. return render(request,'login.html',{'status':'用户名或密码错误'}) #通过模板语言,来在login.html中添加一个status的替换告诉用户{{ status }} return render(request,'login.html')
学习网站 http://www.ziqiangxuetang.com/django/django-intro.html