分页器(paginator)

>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2) >>> p.count #数据总数
4
>>> p.num_pages #总页数
2
>>> type(p.page_range) # `<type 'rangeiterator'>` in Python 2.
<class 'range_iterator'>
>>> p.page_range #页码的列表
range(1, 3) # =========[1,2] >>> page1 = p.page(1) #第1页的page对象
>>> page1
<Page 1 of 2>
>>> page1.object_list #第1页的数据
['john', 'paul'] >>> page2 = p.page(2)
>>> page2.object_list #第2页的数据
['george', 'ringo']
>>> page2.has_next() #是否有下一页
False
>>> page2.has_previous() #是否有上一页
True
>>> page2.has_other_pages() #是否有其他页
True
>>> page2.next_page_number() #下一页的页码
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number() #上一页的页码
1
>>> page2.start_index() # 本页第一条记录的序数(从1开始)
3
>>> page2.end_index() # 本页最后录一条记录的序数(从1开始)
4 >>> p.page(0) #错误的页,抛出异常
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
>>> p.page(3) #错误的页,抛出异常
Traceback (most recent call last):
...
EmptyPage: That page contains no results 另一种错误:

PageNotAnInteger at /index/

That page number is not an integer

实现一个分页效果:

模板:
<ul>
{% for book in book_list %}
  <li>{{ book.title }} {{ book.price }}</li>
{% endfor %} </ul> {# 分页器#}
<ul class="pagination">
{% if book_list.has_previous %}
<li><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>
{% else %}
<li class="disabled"><a href="#">上一页</a></li>
{% endif %} {% for num in p.page_range %}
<li><a href="/index/?page={{ num }}">{{ num }}</a></li>
{% endfor %} {% if book_list.has_next %}
<li><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>
{% else %}
<li class="disabled"><a href="#">下一页</a></li>
{% endif %} </ul>
视图:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def index(request):

    '''
批量导入数据: Booklist=[]
for i in range(100):
Booklist.append(Book(title="book"+str(i),price=30+i*i))
Book.objects.bulk_create(Booklist) ''' book_list=Book.objects.all() paginator = Paginator(book_list, 10)
page = request.GET.get('page',1)
currentPage=int(page) try:
print(page)
book_list = paginator.page(page)
except PageNotAnInteger:
book_list = paginator.page(1)
except EmptyPage:
book_list = paginator.page(paginator.num_pages) return render(request,"index.html",locals())

Django的用户认证

认证登录

from django.contrib import auth

django.contrib.auth中提供了许多方法,这里主要介绍其中的三个:

1 authenticate()

提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数

如果认证信息有效,会返回一个  User  对象。

authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。

当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的!!

user = authenticate(username='someone',password='somepassword')

login(HttpRequest, user)  

该函数接受一个HttpRequest对象,以及一个认证了的User对象

此函数使用django的session框架给某个已认证的用户附加上session id等信息。

from django.contrib.auth import authenticate, login

def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...

3  logout(request) 注销用户

from django.contrib.auth import logout

def logout_view(request):
logout(request)
# Redirect to a success page.

该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错

4 user对象的 is_authenticated()

要求:

1  用户登陆后才能访问某些页面,

2  如果用户没有登录就访问该页面的话直接跳到登录页面

3  用户在跳转的登陆界面中完成登陆后,自动访问跳转到之前访问的地址

方法1:

def my_view(request):
if not request.user.is_authenticated():
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

方法2:login_required函数

django已经为我们设计好了一个用于此种情况的装饰器:login_requierd()

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
...

若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。

并传递  当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

User对象

User 对象属性:username, password(必填项)password用哈希算法保存到数据库

is_staff : 用户是否拥有网站的管理权限.

is_active : 是否允许用户登录, 设置为``False``,可以不用删除用户来禁止 用户登录

User 对象方法  

1  is_authenticated()

如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。
通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。

这个方法很重要, 在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name

2  创建用户

使用 create_user 辅助函数创建用户:

from django.contrib.auth.models import User
user = User.objects.create_user(username='',password='',email='')

3  修改密码set_password(passwd)

这个方法是用来更改密码的,使用步骤:

user=User.objects.get(username='')
user.set_password(passeord='')
user.save

4  check_password(passwd)

用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回 True

示例:注册

def sign_up(request):

    state = None

    if request.method == 'POST':

        password = request.POST.get('password', '')
repeat_password = request.POST.get('repeat_password', '')
email=request.POST.get('email', '')
if password == '' or repeat_password == '':
state = 'empty'
elif password != repeat_password:
state = 'repeat_error'
else:
username = request.POST.get('username', '')
if User.objects.filter(username=username):
state = 'user_exist'
else:
new_user = User.objects.create_user(username=username, password=password,email=email)
new_user.save()
new_my_user = MyUser(user=new_user, telephone=request.POST.get('telephone', ''))
new_my_user.save() return redirect('/book/')
content = {
'state': state,
'user': None,
}
return render(request, 'book/sign_up.html', content)

示例:改密码

@login_required
def set_password(request):
user = request.user
state = None
if request.method == 'POST':
old_password = request.POST.get('old_password', '')
new_password = request.POST.get('new_password', '')
repeat_password = request.POST.get('repeat_password', '')
if user.check_password(old_password):
if not new_password:
state = 'empty'
elif new_password != repeat_password:
state = 'repeat_error'
else:
user.set_password(new_password)
user.save()
return redirect("/log_in/")
else:
state = 'password_error'
content = {
'user': user,
'state': state,
}
return render(request, 'book/set_password.html', content)

FORM

Django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm

关于django的表单系统,主要分两种

基于django.forms.Form:所有表单类的父类

基于django.forms.ModelForm:可以和模型类绑定的Form

需求:向数据库的Info表中添加一些新的个人信息

使用Form的情况

#-----------------------------------------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'^add_info/', views.add_info,name='add_info'), ] #-----------------------------------------models.py
#----------------------------------------- from django.db import models # Create your models here. class Info(models.Model): name = models.CharField(max_length=64)
sex = models.CharField(max_length=64)
birthday = models.CharField(max_length=64)
age=models.CharField(max_length=64)
qualification=models.CharField(max_length=64)
job=models.CharField(max_length=64)
email=models.CharField(max_length=64,default='') class Hobby(models.Model):
item=models.CharField(max_length=64) #-----------------------------------------form.py
#----------------------------------------- from django import forms
from app01 import models
from django.core.exceptions import ValidationError class Info_form(forms.Form): def validate_name(value):
try:
models.Info.objects.get(name=value)
raise ValidationError('%s 的信息已经存在!'%value)
except models.Info.DoesNotExist:
pass sex_choice=((0,'男'),
(1,'女'))#select的数据可以像这样写,也可以在另外一张表中动态去拿 name = forms.CharField(validators=[validate_name],label='姓名',error_messages={'required':'必填'}) age = forms.CharField(label='年龄',error_messages={'required':'必填'}) # sex = forms.CharField(label='性别',error_messages={'required':'必填',},)
sex=forms.IntegerField(widget=forms.widgets.Select(choices=sex_choice, attrs={'class':'setform2'}
)) birthday = forms.CharField(label='生日',error_messages={'required':'必填'}) qualification = forms.CharField(label='学历',error_messages={'required':'必填'},
widget=forms.TextInput(attrs={'class':'formset',
'placeholder':'本科'
}
))
email=forms.EmailField(max_length=100,min_length=10,,error_messages={'invalid': u'请填写有效邮箱地址。'}) job = forms.CharField(label='工作',error_messages={'required':'必填'}) def __init__(self,*args,**kwargs): super(Info_form,self).__init__(*args,**kwargs) self.fields['hobby']=forms.CharField(widget=forms.widgets.Select(choices=models.Hobby.objects.values_list('id','item'))) #-------------------------------------------------------views.py
#------------------------------------------------------- from django.shortcuts import render,HttpResponse # Create your views here. from app01.models import * from app01.forms import * def add_info(req):
if req.method=='POST': Info_form_obj=Info_form(req.POST)
if Info_form_obj.is_valid(): Info.objects.create(name=Info_form_obj.cleaned_data['name'],
age=Info_form_obj.cleaned_data['age'],
sex=Info_form_obj.cleaned_data['sex'],
birthday=Info_form_obj.cleaned_data['birthday'],
qualification=Info_form_obj.cleaned_data['qualification'],
job=Info_form_obj.cleaned_data['job']
)
return HttpResponse('添加成功!')
else: error_obj=Info_form_obj.errors
print('***************')
print(type(error_obj))#<class 'django.forms.utils.ErrorDict'> print(error_obj['name'][0])#必填 print(error_obj.get('age'))#<ul class="errorlist"><li>必填</li></ul>
return render(req,'add_info.html',{'form_obj':Info_form_obj,'error_obj':error_obj}) Info_form_obj=Info_form()
return render(req,'add_info.html',{'form_obj':Info_form_obj}) #------------------------------------------------------add_info.html
#------------------------------------------------------- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加个人信息</title>
<style>
.formset{
color: rebeccapurple;
border: dashed cadetblue;
}
</style>
</head>
<body>
<form action="{% url 'add_info' %}" method="post"> <p>姓名{{ form_obj.name }}{{ error_obj.name.0 }}</p>
<p>年龄{{ form_obj.age }}{{ error_obj.age.0 }}</p>
<p>生日{{ form_obj.birthday }}{{ error_obj.birthday.0 }}</p>
<p>工作{{ form_obj.job }}<span>{{ error_obj.job }}</span></p>
<p>学历{{ form_obj.qualification }}<span>{{ error_obj.qualification }}</span></p>
<p>性别{{ form_obj.sex }}<span>{{ error_obj.sex }}</span></p>
<p>邮箱{{ form_obj.email }}<span>{{ error_obj.email }}</span></p>
<p>爱好{{ form_obj.hobby }}<span>{{ error_obj.hobby }}</span></p> {# {{ form_obj.as_p }}#} <input type="submit" value="提交"><br>
{% csrf_token %}
</form>
</body>
</html>

DjangoForm补充:

问题1:  注册页面输入为空,报错:keyError:找不到password

def clean(self):

        print("---",self.cleaned_data)
# if self.cleaned_data["password"]==self.cleaned_data["repeat_password"]:
# 报错原因:self.cleaned_data是干净数据,如果页面没有输入内容,则self.cleaned_data没有password。
改如下:
if self.cleaned_data.get("password")==self.cleaned_data.get("repeat_password"):
return self.cleaned_data
else:
raise ValidationError("两次密码不一致")

问题2:  为什么要用全局clean()

按子段顺序一一校验,即校验到username时,你无法使用self.cleaned_data.get("password")。

而局部钩子使用完,到全局时,已经可以使用所有的self.cleaned_data

总结Django的Form表单的钩子:

钩子解决的是自定制校验规则

局部钩子:校验单个字段,例如:用户名最短5个字符,最长12个字符;密码必须大于8位,验证码必须正确

全局钩子:校验信息涉及多个字段,例如:密码和重复密码必须一致

注意:

form表单类继承问题:

Django--分页器(paginator)、Django的用户认证、Django的FORM表单的更多相关文章

  1. 怎样使我们的用户不再抵触填写Form表单?

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://blog.bitsrc.io/8-tips-for-an-awesome-sign ...

  2. Django中三种方式写form表单

    除了在html中自己手写form表单外,django还可以通过 继承django.forms.Form 或django.forms.ModelForm两个类来自动生成form表单,下面依次利用三种方式 ...

  3. [Django实战] 第3篇 - 用户认证(初始配置)

    当大家打开一个网站时,第一步做什么?大部分一定是先登录吧,所以我们就从用户认证开始. 打开用户认证 Django本身已经提供了用户认证模块,使用它可以大大简化用户认证模块的开发,默认情况下,用户认证模 ...

  4. Django 中的Form表单认证

    一.Form表单   1.1 Form的几个功能 验证用户数据(显示错误信息) 初始化页面显示内容 HTML Form提交保留上次提交数据 生成HTML标签   1.2 创建表单类Form 1. 创建 ...

  5. Django获取用户form表单

    首先创建一个Django 的工程项目 前面我们说过了,那到一个项目首先把模板路径,和静态路径在settings.py设置好以后,在开始写代码,写代码也要按照我们以前说的那个工程目录结构写. 现在我们做 ...

  6. Day19 Django之Form表单验证、CSRF、Cookie、Session和Model操作

    一.Form表单验证 用于做用户提交数据的验证1.自定义规则 a.自定义规则(类,字段名==html中的name值)b.数据提交-规则进行匹配代码如下: """day19 ...

  7. Django学习笔记(6)——Form表单

    知识储备:HTML表单form学习 表单,在前端页面中属于最常见的一个东西了.基本上网站信息的提交都用到了表单,所以下面来学习Django中优雅的表单系统:Form 表单的主要作用是在网页上提供一个图 ...

  8. django之form表单验证

    django中的Form一般有两种功能: 输入html 验证用户输入 #!/usr/bin/env python # -*- coding:utf- -*- import re from django ...

  9. django中form表单的提交:

    一,关于表单: 表单在百度百科的解释:   表单在网页中主要负责数据采集功能.一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单域 ...

随机推荐

  1. MyEclipse使用过程中的问题及对应设置的总结

    1.关闭 Javaweb项目中的updating index : Window => Preferences => Myeclipse Enterprise Workbench => ...

  2. 阿里云数据库备份DBS商业化发布,数据库实时备份到OSS

    数据库备份DBS已于2018年5月17日正式商业化发布. 数据库备份(Database Backup,简称DBS)是为数据库提供连续数据保护.低成本的备份服务. 它可以为多种环境的数据提供强有力的保护 ...

  3. SQLmap注入

    一.安装 先安装Python2.7 下载SQLmap:http://sqlmap.org/ 下载文件解压到Python文件目录下 然后设置环境变量:D:\Python27\sqlmap 在cmd查看是 ...

  4. python中的__init__

    __init__ __init__中__表示系统默认命名,init是初始化的意思.由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去.以学生类为例,通过定义 ...

  5. HDU-4475 Downward paths(找规律)

    Downward paths Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  6. CATiledLayer显示超大图片的解决方案

    先对图片进行了裁剪 -> 很多小图片, 然后再根据显示 进行绘制 - (void)viewDidLoad { [super viewDidLoad]; [self cutImageAndSave ...

  7. leetcode-解题记录 557. 反转字符串中的单词 III

    题目: 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode contest" 输出 ...

  8. TP5数据库事务操作

    使用事务处理的话,需要数据库引擎支持事务处理.比如 MySQL 的 MyISAM 不支持事务处理,需要使用 InnoDB 引擎. 使用 transaction 方法操作数据库事务,当发生异常会自动回滚 ...

  9. Linux下docker安装教程

    目前最新版本的docker19.03支持nvidia显卡与容器的无缝对接,从而摆脱了对nvidia-docker的依赖.因此毫不犹豫安装19.03版本的docker,安装教程可参考官方教程Centos ...

  10. linux下部署springboot vue项目

    使用的工具是 XFTP5 XSHELL5 docker pull gmaslowski/jdk 拉取jdk docker images 查询下载的镜像ID (如:390b58b1be42) docke ...