django -- 实现ORM登录

前戏

上篇文章写了一个简单的登录页面,那我们可不可以实现一个简单的登录功能呢?如果登录成功,给返回一个页面,失败给出错误的提示呢?

在之前学HTML的时候,我们知道,网页在往服务器提交数据的时候,都是在form表单里,并且要满足下面的几个条件:

1.form标签必须要有action和method属性,如果是文件上传还要加上下面的一句

<form action="www.baidu.com" enctype="multipart/form-data"></form>

 

2.所有获取用户的标签必须放在form表单中,必须要有name属性

3.必须要有submit按钮

Django必学三件套

Django 基础必会三件套,render,HttpResponse,redirect

from django.shortcuts import HttpResponse, render, redirect

HttpResponse:返回一个指定的字符串

render:返回一个HTML文件

redirect:跳转url,如果是同一个网站,可以省略域名,如果想跳转到其他网站,要写上全部的网址

 

知道了form表单提交数据的三个要素后,我们修改一下login.html文件

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta http-equiv="content-Type" charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title><link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css"><link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.css"><style>body {background-color: #eeeeee;}.login-box {margin-top: 50px;}</style>
</head>
<body>
<div class="container"><div class="row"><div class="col-md-4 col-md-offset-4 login-box"><form class="form-horizontal" action="/login/" method="post"><div class="col-sm-9"><h2 class="text-center">请登录</h2></div><div class="form-group"><div class="col-sm-9"><div class="input-group margin-bottom-sm"><label for="email" class="hidden">邮箱</label><span class="input-group-addon"><i class="fa fa-envelope-o fa-fw"></i></span><input class="form-control" type="text" name="email" id="email" placeholder="您的邮箱地址"></div><span class="help-block"></span></div></div><div class="form-group"><div class="col-sm-9"><div class="input-group"><label for="password" class="hidden" >密码</label><span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span><input class="form-control" type="password" name="pwd" id="password" placeholder="请输入密码"></div><span class="help-block"></span></div></div><div class="form-group"><div class="col-sm-9"><div class="checkbox"><label><input type="checkbox"> 记住我</label></div></div></div><div class="form-group"><div class="col-sm-9"><button type="submit" id="b1" class="btn btn-block btn-primary">登录</button><p style="color: red;text-align: center">{{ error_msg}}</p></div></div></form></div></div>
</div><script src="/static/jquery-3.3.1.js"></script>
<script>$("#b1").click(function () {$("input:not([type='checkbox'])").each(function () {// 判断值为不为空if ($(this).val().length === 0) {// 展示错误提示var errMsgPrefix = $(this).prev().prev().text();$(this).parent().next().text(errMsgPrefix + "不能为空");$(this).parent().parent().parent().addClass("has-error");}});});// 给输入框绑定获取焦点的事件
    $("input:not([type='checkbox'])").focus(function () {// 清空错误提示
        $(this).parent().next().text("");// 移除父标签的has-error
        $(this).parent().parent().removeClass("has-error");});
</script>
</body>
</html>
View Code

注意:action="/login/"要加/,要不然下面的错误时路径会是这样的:login/login

我们在去login函数里打印一下request.GET

def login(request):print(request.GET)return render(request,'login.html')

结果:

[02/Jul/2019 20:46:35] "GET /login/login?email=%40163.com&pwd=123 HTTP/1.1" 200 3532
<QueryDict: {'email': ['@163.com'], 'pwd': ['123']}>

可以看到,我们在登录页面输入的邮箱和密码都以字典的方式传给了后台,其中字典的key就是我们在html文件里对应标签的name属性,如果没有name属性,则为空

 

我们提交数据的时候,通常都是以post方法来提交的,get通常是用于获取数据的,那我们把login.html文件里的method=‘get’改为post,在来试一下

<form class="form-horizontal" action="login" method="post">

 

上面的错误信息告诉了我们:CSRF验证失败。请求中止。我们只需要把setting.py里的CSRF注释掉就可以了

'django.middleware.csrf.CsrfViewMiddleware' #注释掉这行

先去把login函数里的GET换成POST

print(request.POST),然后就可以正常访问了

那我们登录之后能不能给浏览器返回一个“登录成功”的提示呢?

 

index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta http-equiv="content-Type" charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title><link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
</head>
<body><div class="container"><div class="row"><div class="col-md-12"><div class="page-header"><h1>信息收集卡<small>共三步</small></h1></div><div class="progress"><div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="60" aria-valuemin="0"aria-valuemax="100" style="width: 33%;">1/3</div></div><!--面板--><div class="panel panel-primary"><div class="panel-heading">基本信息<span class="glyphicon glyphicon-pushpin pull-right"></span></div><div class="panel-body"><!--表单--><form class="form-horizontal"><div class="form-group"><label for="inputEmail3" class="col-sm-2 control-label">姓名</label><div class="col-sm-4"><input type="text" class="form-control" id="inputEmail3" placeholder="Email"></div></div><div class="form-group"><label for="inputPassword3" class="col-sm-2 control-label">手机号</label><div class="col-sm-4"><input type="text" class="form-control" id="inputPassword3" placeholder="Password"></div></div><div class="form-group"><label for="inputPassword3" class="col-sm-2 control-label">邮箱</label><div class="col-sm-4"><input type="email" class="form-control" id="inputPassword" placeholder="Password"></div></div><div class="form-group"><label for="inputPassword3" class="col-sm-2 control-label">密码</label><div class="col-sm-4"><input type="password" class="form-control" id="inputPassword4" placeholder="Password"></div></div><div class="form-group"><label for="inputPassword3" class="col-sm-2 control-label">头像</label><div class="col-sm-4"><input type="file" id="inputPassword5" placeholder="Password"><span class="help-block">只支持jpg,png,gif格式</span></div></div><hr><div class="form-group"><label for="inputPassword3" class="col-sm-2 control-label">属性</label><div class="col-sm-10"><div class="radio"><label><input type="radio" name="optionsRadios" id="optionsRadios1" value="option1"checked>Option one is this and that&mdash;be sure to include why it's great</label></div><div class="radio"><label><input type="radio" name="optionsRadios" id="optionsRadios2" value="option2">Option two can be something else and selecting it will deselect option one</label></div><div class="radio disabled"><label><input type="radio" name="optionsRadios" id="optionsRadios3" value="option3"disabled>Option three is disabled</label></div></div></div></form></div></div><!--下一步按钮--><button class="btn btn-success pull-right">下一步</button></div></div>
</div>
</body>
</html>
View Code

 先在view里创建一个index的函数

 
def index(request):
return render(request,"index.html")

这里我们需要导入HttpResponse,然后再url.py新增index的路径

from . import views
urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^login/', views.login),url(r'^index/', views.index),
]

在login函数里写如下代码

def login(request):if request.method == 'POST':email = request.POST.get('email')pwd = request.POST.get('pwd')if email == 'zouzou' and pwd == '123':return redirect('/index/')# return HttpResponse('ok')else:return render(request,'login.html')

这样我们如果输入的是zouzou和123,则会跳转到index页面,那如果我们需要错误的时候给我们提示怎么办呢?django提供了我们模版语言;{{变量名}},我们在login.html的button按钮下面加入如下代码

<button type="submit" id="b1" class="btn btn-block btn-primary">登录</button><p style="color: red;text-align: center">{{ error_msg}}</p>

在去修改login函数里的代码

def login(request):error_msg=''if request.method == 'POST':  #如果是post,表示提交数据email = request.POST.get('email')pwd = request.POST.get('pwd')if email == 'zouzou' and pwd == '123':#登录成功跳转到index页面return redirect('/index/')# return HttpResponse('ok')else:#登录失败,提示用户名密码错误error_msg = '邮箱或密码错误'#如果是GET,表示要获取这个页面return render(request,'login.html',{"error_msg":error_msg})

这样,我们输入正确的邮箱和密码就会跳转到index页面,错误的会提示

 app

上面我们把login函数和index函数都放到了views.py文件里面。试想一下,如果我们的项目有成百上千和函数呢?放到一个py文件里是不是很麻烦。

python给我们提供了一个app,我们可以把一个模块放到一个app里,可以有多个app,不同的功能放到不同的app里面。

 

创建app:

如下我们创建了一个叫“appTest01”的项目

python manage.py startapp appTest01

创建完app后,我们要告诉Django我们创建了一个叫“appTest01”的app,去setting.py里加上下面的代码。

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','appTest01.apps.Apptest01Config', # 告诉django我们创建了一个叫appTest01的app# 'appTest01',  #  上面代码的简写方式
]

上面的设置好了之后,我们把之前在view.py里写的代码放到刚创建的appTest01下的view.py里面,然后去url.py里把导入的view.py改一下。启动我们的项目,访问登录页面,能正常访问就表示我们的设置是没有问题的

ORM

前面我们的邮箱和密码是写死的。我们可不可以从数据库里面读取数据做一个判断呢?这时我们就要用到ORM了,那什么是ORM呢?

ORM就是一群写代码的,懒的写sql语句,写了一个工具,自动生成sql语句

ORM:Object Relational Mapping(关系对象映射)

类名对应------------》数据库中的表名

类属性对应---------》数据库里的字段

类实例对应---------》数据库表里的一行数据

 

ORM的优势

Django的orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句;所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite....,如果数据库移只需要更换Django的数据库引擎即可

 

ORM的缺点就是执行效率低

1.创建数据库

由于ORM没有没有创建数据库的方法,所以我们手动创建一个数据库:

create database mysite;

2.告诉Django连接哪个数据库

因为Django默认的数据库是sqlite3,我们要使用mysql,所以要告诉mysql,去setting.py里修改如下代码

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql',  # 连接数据库的类型'NAME': 'mysite',  # 数据库名'HOST': '127.0.0.1',  # 数据库主机地址'PORT': 3306,  # 数据库的端口'USER': 'root',  # 登录数据库的用户名'PASSWORD': '123456',  # 登录数据库的密码
    }
}

3.用什么连接数据库

上面我们已经告诉了django连接哪个数据库,那用什么连?利用第三方的包,比如第三方包:pymysql和MySQLdb,因为MySQLdb不支持python3,所以我们使用pymysql来连接数据库,之前也写过pymysql连接mysql的文章

去和setting.py同级的__init__.py里告诉Django用pymysql模块代替默认的MySQLdb去连接MySQL数据库,写上如下代码

import pymysqlpymysql.install_as_MySQLdb()

4.创建数据表

数据库已经配置好了,也告诉了用什么连,然后我们使用ORM去创建一个数据表。

在appTest01/models.py的文件中创建类(只能在这里面创建),类必须继承models.Model

from django.db import models# Create your models here.class User(models.Model):id = models.AutoField(primary_key=True)   # 创建一个自增的id作为主键email = models.CharField(max_length=32)   # varchar(32)pwd = models.CharField(max_length=32)     # varchar(32)

代码解释:

我们创建了一个User的类,上面也说过,类名对应的数据库表,所以会给我们创建一个User的数据表。类下面的就是ORM的语法,创建了三个字段,分别是id(主键)和长度为varchar(32)的email和pwd字段

5.生成数据表

现在我们已经万事具备,只欠东风了,只要生成数据表就可以了,ORM提供了我们两条命令来生成数据表

1.

python manage.py makemigrations  #根据app下的migrations目录中的记录,检测当前model层代码是否发生变化

结果:

Migrations for 'appTest01':appTest01\migrations\0001_initial.py- Create model User

2.执行完下面的代码如果都显示OK就表示数据表创建成功了

python manage.py migrate  #把orm代码转换成sql语句去数据库执行

使用pycharm连接mysql数据库

点击右边的DataBase

 

 

使用ORM查询数据

上面的apptest01_user是我们创建的表,其他的都是django默认帮我们创建的。我们往数据表里插几条数据

这样,数据我们有了,那我们怎么获取到数据库里的数据和用户输入的数据对比呢?ORM提供了我们一种User.objects.filter(email='', pwd='') 的方法来查询数据

注意:前面的Uer是我们的数据表名,email和pwd是我们数据表里的字段,那我们是不是可以修改一下登录函数了呢

from django.shortcuts import render,HttpResponse,redirect
from appTest01.models import User
def login(request):error_msg=''if request.method == 'POST':  #如果是post,表示提交数据ema = request.POST.get('email')password = request.POST.get('pwd')res = User.objects.filter(email=ema,pwd=password)print(res)if res:#登录成功跳转到index页面return redirect('/index/')# return HttpResponse('ok')else:#登录失败,提示用户名密码错误error_msg = '邮箱或密码错误'#如果是GET,表示要获取这个页面return render(request,'login.html',{"error_msg":error_msg})def index(request):return render(request,"index.html")

 

如果查询到res的值就是

<QuerySet [<User: User object>]>

查询不到res的值就是

<QuerySet []>

如果要获取对应的值,可以用下面的方法

print(res[0].id,res[0].email,res[0].pwd)  # 获取到数据库里对应的字段

对象.属性《-----》数据表里具体字段的值

总结:

1. form表单提交数据的三个要素
  1.1. form标签必须要有action和method属性
  1.2. 所有获取用户输入的标签必须放在form表单中,必须要有name属性
  1.3. 必须要有submit按钮

 

2. Django 基础必会三件套
from django.shortcuts import HttpResponse, render, redirect
  2.1. HttpResponse      返回一个指定的字符串时
  2.2. render        返回一个HTML文件
  2.3. redirect      跳转

 


3. request相关的属性
  3.1. request.method --> 返回的是请求的方法(全大写):GET/POST ...
  3.2. request.GET --> 取得是URL里面的参数,类似于字典的数据结构
  3.3. request.POST --> post提交的数据,类似于字典的数据结构

4. Django的模板语言
{{ 变量名 }}

 

 

5. Django项目app --> 项目中又分了一级Python包,不同的功能放到不同的包里面
  5.1. 创建app
    python manage.py startapp app01
  5.2. 告诉Django创建了一个app
    在settings.py找那个的INSTALLED_APPS中添加新创建的app

6. Django中ORM的使用
  6.1. 用处
    6.1.1. 操作数据表
    6.2.2. 操作数据行


  6.2. 使用
    6.2.1. 手动创建一个数据库
      -> create database mysite;
    6.2.2. 告诉Django连哪个数据库
      DATABASES = {
        'default': {
          'ENGINE': 'django.db.backends.mysql', # 连接数据库的类型
          'NAME': 'mysite', # 数据库名
          'HOST': '127.0.0.1', # 数据库主机地址
          'PORT': 3306, # 数据库的端口
          'USER': 'root',
          'PASSWORD': '123456',
          }
         }
  6.3. 用什么连数据库?
    利用第三方的包,比如第三方包:pymysql和MySQLdb
    告诉Django用pymysql模块代替默认的MySQLdb去连接MySQL数据库
    和settings.py同级的__init__.py文件,写上:
  

import pymysql
pymysql.install_as_MySQLdb()

 

  6.4. 在app/models.py的文件中创建类,只能在这里面创建
    类必须继承models.Model


  6.5. 两个命令
    6.5.1. python manage.py makemigrations --> 把models.py的变更记录一下,注意要保证数据库里的和ORM变更记录一样,否则会报错
    6.5.2. python manage.py migrate --> 把上面的变更记录翻译成SQL语句,去数据库执行
    6.5.3. ORM查询
      User.objects.filter(email='', pwd='')

    6.5.4.数据表名或结构变了都要重新执行一下6.5.3

转载于:https://www.cnblogs.com/zouzou-busy/p/11123780.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/386515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美团点评APP在移动网络性能优化的实践,通用流行框架大全

" 对于程序员来说&#xff0c;如果哪一天开始他停止了学习&#xff0c;那么他的职业生涯便开始宣告消亡。” 高薪的IT行业是众多年轻人的职业梦想&#xff0c;然而&#xff0c;一旦身入其中却发觉没有想像中那么美好。被称为IT蓝领的编程员&#xff0c;工作强度大&#xf…

centos7.0利用yum快速安装mysql8.0

我这里直接使用MySQL Yum存储库的方式快速安装&#xff1a; 抽象 MySQL Yum存储库提供用于在Linux平台上安装MySQL服务器&#xff0c;客户端和其他组件的RPM包。这些软件包还可以升级和替换从Linux发行版本机软件存储库安装的任何第三方MySQL软件包&#xff0c;如果可以从MySQL…

腾讯3轮面试都问了Android事件分发,论程序员成长的正确姿势

前言 这些题目是网友去美团等一线互联网公司面试被问到的题目。笔者从自身面试经历、各大网络社交技术平台搜集整理而成&#xff0c;熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。 主要分为以下几部分&#xff1a; &#xff08;1&#xff09;Android面试题 …

happens-before规则和as-if-serial语义

概述 本文大部分整理自《Java并发编程的艺术》&#xff0c;温故而知新&#xff0c;加深对基础的理解程度。 指令序列的重排序 我们在编写代码的时候&#xff0c;通常自上而下编写&#xff0c;那么希望执行的顺序&#xff0c;理论上也是逐步串行执行&#xff0c;但是为了提高…

贴片晶振无源石英谐振器直插晶振

贴片晶振 贴片晶振3.579M~25MHz无源石英谐振器直插晶振 文章目录 贴片晶振前言一、贴片晶振3.579M~25MHz无源石英谐振器直插晶振二、属性三、技术参数总结前言 贴片晶振(Surface Mount Crystal Oscillator)是一种采用表面贴装技术进行安装的晶振。它的主要特点是封装小巧、安…

这些新技术你们都知道吗?成功收获美团,小米安卓offer

前言 近期被两则消息刷屏&#xff0c;【字节跳动持续大规模招聘&#xff0c;全年校招超过1万人】【腾讯有史以来最大规模的校招启动】当然Android岗位也包含在内&#xff0c;因此Android还是有很多机会的。结合往期面试的同学&#xff08;主要是校招&#xff09;经验&#xff…

这些新技术你们都知道吗?看这一篇就够了!

前言 现在已经进入招聘季节&#xff0c;本篇文章旨在分享知名互联网企业面试官面试方法和心得&#xff0c;希望通过本文的阅读能给程序员带来不一样的面试体验和感受&#xff0c;放松面试心态&#xff0c;积极备战&#xff01; 面试题 PS&#xff1a;由于文章篇幅问题&#x…

这份1307页Android面试全套真题解析,源码+原理+手写框架

前言 前不久&#xff0c;几个朋友聚会&#xff0c;谈到了现在的后辈&#xff0c;我就说起了那个大三就已经拿到网易offer的小学弟。 这个学弟是00后&#xff0c;专升本进入我们学校的。进来后就非常努力&#xff0c;每次上课都是第一个到教室的&#xff0c;每次都是坐第一排&…

[转]OpenContrail 体系架构文档

OpenContrail 体系架构文档英文原文&#xff1a;http://opencontrail.org/opencontrail-architecture-documentation/ 翻译者&#xff1a;KkBLuE知行合一 其微信号&#xff1a;kkbluepublic&#xff0c; SDNAP.com翻译整理 OpenContrail 体系架构文档 1 概述 1.1 使用案例 1…

这份354页笔记的Android进阶知识+大厂高频面试题,绝对干货

程序员与别的专业有所不同&#xff0c;其他专业都是越老越香&#xff0c;而程序员却是一个例外&#xff0c;因为计算机技术更新太快&#xff0c;而且工作强度很大&#xff0c;因此大部分程序员只会写 3 年代码。3 年后要不晋升做项目经理&#xff0c;要么转行&#xff0c;个别研…

这是一份用心整理的Android面试总结,聪明人已经收藏了!

前言 本文想分享的是如何准备阿里面试的以及面试过程的所想所得&#xff0c;希望能帮到你。 首先&#xff0c;可能要让你们失望的是&#xff0c;这篇文章不会有大篇幅的面试题答案。如果想要看这方面的内容&#xff0c;可以看我之前的文章。感谢关注 很多人准备面试的时候&a…

git 技能图

---- 转载于:https://www.cnblogs.com/WHWWHW/p/11136606.html

AtomicStampedReference源码分析

之前的文章已经介绍过CAS的操作原理&#xff0c;它虽然能够保证数据的原子性&#xff0c;但还是会有一个ABA的问题。 那么什么是ABA的问题呢&#xff1f;假设有一个共享变量“num”,有个线程A在第一次进行修改的时候把num的值修改成了33。修改成功之后&#xff0c;紧接着又立刻…

django:bootstrap table加载django返回的数据

bootstrap table加载表格数据有两类方式&#xff1a; 一种通过data属性的方式配置&#xff0c;一种是javascipt方式配置 这里看js配置方式&#xff1a; 1、当数据源为.json文件时 url参数写上json文件的地址就行&#xff0c;但是json文件格式必须为json格式(2种): a:一种为json…

这是一份面向Android开发者的复习指南,成功入职字节跳动

前言 19年6月份从网易云音乐离开&#xff0c;放弃了留学机会&#xff0c;开始了人生的第一次创业&#xff0c;前后尝试了两个项目&#xff0c;因为个人能力与时机因素都失败了&#xff0c;虽然没能享受到创业所能够带来高杠杆物质上的回报&#xff0c;但是对个人软技能和自我边…

这篇文章可以满足你80%日常工作!一线互联网公司面经总结

前言 最近发现大家都喜欢看面试相关的文章&#xff0c;我也跟一波风&#xff0c;总结了一下我面试中所遇到的问题总结&#xff0c;分享一下面试中被问的最多的一些问题。 希望对正在找工作的朋友提供一些帮助。 好了话不多说&#xff0c;进入正题。 作为安卓开发者&#xff…

MSCRM二次开发实现自动编号功能

功能描述&#xff1a;对客户实体实现自动编号功能&#xff0c;1、2、3、4...... 自动编号存放于属性accountnumber.原  理&#xff1a;在mscrm服务器用一个文本文件存放当前最新编号&#xff0c;每当创建客户记录时在PreCreate事件接口做以下步骤&#xff1a;1、锁定文本文件…

这篇文章可以满足你80%日常工作!成功入职腾讯

什么是中年危机 根据权威数据显示&#xff0c;国内IT程序员鼎盛时期是在25-27岁左右&#xff0c;30岁对于程序员而言完全是一个38线&#xff0c;接着就是转业转岗的事情&#xff0c;这一点在业界也算是一个共识了。 大学毕业步入IT行业普遍年龄也是在22岁左右&#xff0c;然而…

java并发synchronized 锁的膨胀过程(锁的升级过程)深入剖析(2)

接下来我们分析两个批量偏向撤销的相关案例&#xff08;禁止偏向锁延迟的情况下&#xff1a;-XX:UseBiasedLocking -XX:BiasedLockingStartupDelay0&#xff09;&#xff1a; 案例一&#xff1a; 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…

连续四年百度Android岗必问面试题!Android校招面试指南

前言 刚从阿里面试回来&#xff0c;想和大家分享一些我的面试经验&#xff0c;以及面试题目。 这篇文章将会更加聚焦在面试前需要看哪些资料&#xff0c;一些面试技巧以及一些这次的面试考题。 面试经历 7月确定想走后开始看各种面经&#xff0c;复习基础知识&#xff0c;月…