本节内容

  1. Django的分页

  2. Form

  3. 中间件

1 Django 分页

1.1 Django自带的分页

1.首先来看下我的测试数据环境

  1. ############ models.py ##############
  2. class User(models.Model):
  3. username = models.CharField(max_length=32)
  4. password = models.CharField(max_length=32)
  5.  
  6. class Host(models.Model):
  7. hostname = models.CharField(max_length=32)
  8. ip = models.GenericIPAddressField()
  9. user = models.ForeignKey('User')
  10.  
  11. ############ views.py ##############
  12. from app import models
  13. # Create your views here.
  14. def create(request):
  15. models.User.objects.create(username='helei',password='')
  16. models.User.objects.create(username='alex',password='')
  17. models.User.objects.create(username='egon',password='')
  18. for i in range(1,201):
  19. models.Host.objects.create(hostname='www.%s.com'%i,ip='192.168.1.%s'%i,user_id=1)
  20. return HttpResponse('添加成功')
  21.  
  22. ############ urls.py ##############
  23. from app import views
  24. urlpatterns = [
  25. url(r'^admin/', admin.site.urls),
  26. url(r'^create/$', views.create),
  27. ]

2.来配置一个index来显示数据

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Index</title>
  6. <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
  7. </head>
  8. <body>
  9. <div style="width: 800px;margin: 0 auto">
  10. <table class="table table-hover">
  11. <h1>主机列表</h1>
  12. <tr>
  13. <th>ID</th>
  14. <th>主机名</th>
  15. <th>IP</th>
  16. </tr>
  17. {% for obj in obj_list %}
  18. <tr>
  19. <td>{{ obj.id }}</td>
  20. <td>{{ obj.hostname }}</td>
  21. <td>{{ obj.ip }}</td>
  22. </tr>
  23. {% endfor %}
  24. </table>
  25. </div>
  26. </body>
  27. </html>
  28.  
  29. ############### views.py ##############
  30. def index(request):
  31. obj_list = models.Host.objects.all()
  32. return render(request,'index.html',{'obj_list':obj_list})

index.html and views.py

3.页面内容正常显示,但是显示的是所有的数据信息,不好看。下面我们利用Django自带的分页功能来美化~?

在使用Django的分页是会用到Django的一个模块 paginator ,下面介绍下这个模块

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

EmptyPage, PageNotAnInteger为两个报错的信息,

这里主要介绍paginator 

  1. #### 参数说明 ####
  2. paginator = Paginator(L, 10)
  3. # per_page: 每页显示条目数量
  4. # count: 数据总个数
  5. # num_pages:总页数
  6. # page_range:总页数的索引范围,如: (1,10),(1,200)
  7. # page: page对象
  8.  
  9. posts = paginator.page(current_page)
  10. # has_next 是否有下一页
  11. # next_page_number 下一页页码
  12. # has_previous 是否有上一页
  13. # previous_page_number 上一页页码
  14. # object_list 分页之后的数据列表
  15. # number 当前页
  16. # paginator paginator对象

终于写完了。 利用Django自带的分页函数最多就搞成这样了。 最多了。maybe

  1. ######## urls.py ########
  2. from app import views
  3. urlpatterns = [
  4. url(r'^admin/', admin.site.urls),
  5. url(r'^create/$', views.create),
  6. url(r'^index/$', views.index),
  7. url(r'^index/(?P<pid>\d+)$', views.index),
  8. ]
  9.  
  10. ######## views.py ########
  11. def index(request,pid=1):
  12. obj_list = models.Host.objects.all() # 所有的数据对象
  13. page_obj = Paginator(obj_list,10) # 定义一个分页对象实例
  14. pages = page_obj.page(pid) # 传递页数给page_obj对象
  15. return render(request,'index.html',{'pages':pages}) # pages.object_list 分页后的数据
  16.  
  17. ######## index.html ########
  18. <!DOCTYPE html>
  19. <html lang="en">
  20. <head>
  21. <meta charset="UTF-8">
  22. <title>Index</title>
  23. <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
  24. </head>
  25. <body>
  26. <div style="width: 800px;margin: 0 auto">
  27. <table class="table table-hover">
  28. <h1>主机列表</h1>
  29. <tr>
  30. <th>ID</th>
  31. <th>主机名</th>
  32. <th>IP</th>
  33. </tr>
  34. {% for obj in pages.object_list %}
  35. <tr>
  36. <td>{{ obj.id }}</td>
  37. <td>{{ obj.hostname }}</td>
  38. <td>{{ obj.ip }}</td>
  39. </tr>
  40. {% endfor %}
  41. </table>
  42. <nav aria-label="...">
  43. <ul class="pagination">
  44. {% if pages.has_previous %}
  45. <li><a href="/index/{{ pages.previous_page_number }}">上一页</a></li>
  46. {% endif %}
  47. {% for row in pages.paginator.page_range %}
  48. {% if row == pages.number %}
  49. <li class="active"><a href="{{ row }}">{{ row }}</a></li>
  50. {% else %}
  51. <li><a href="{{ row }}">{{ row }}</a></li>
  52. {% endif %}
  53. {% endfor %}
  54. {% if pages.has_next %}
  55. <li><a href="/index/{{ pages.next_page_number }}">下一页</a></li>
  56. {% endif %}
  57. </ul>
  58. </nav>
  59.  
  60. </div>
  61. </body>
  62. </html>

2.1 自定义分页

上面的已经很好了,但是不是最屌的。 哈哈哈哈,不多说了,按照上边的思路,自己写一个分页函数来实现和上边基本类似的功能。go

写好了, 但是都写好了,分别说下各个函数中的代码功能吧。

1.urls.py

这里主要看最后的两个(自定义分页专用),

这里简单说明一下,匹配以/home/开头的url,都跳转到views.home进行处理,这里我给了home函数默认参数,让他可以处理这两个URL的数据。这一点可以在views.py中的home函数中看到。

  1. from app import views
  2. urlpatterns = [
  3. url(r'^admin/', admin.site.urls),
  4. url(r'^create/$', views.create),
  5. url(r'^index/$', views.index),
  6. url(r'^index/(?P<pid>\d+)$', views.index),
  7. url(r'^home/$', views.home), # 自定义分页专用
  8. url(r'^home/(?P<pid>\d+)$', views.home), # 自定义分页专用
  9. ]

2.views.py

第一行的模块导入为我们自定义的一个对数据分页处理操作的一个函数,这里简单说明下他的使用,

  1. class Page(object):
    def __init__(self,currout_page,num,data_count,url,page_num):
  1. currout_page:当前页码
  1. num:每页显示数据条数
  1. data_count:数据总条数
  1. url:跳转的url
  1. page_num:每页跳转标签的个数
  2.  
  3. Page类中有三个函数
  1. start()  根据用户给的当前页数,返回当前页数数据的开始索引
  1. end()  根据用户给的当前页数,返回当前页数数据的结束索引
  1. pagestr()  更加用户给定的参数,返回html标签,该html会生成上下页和页码信息
  1. from utils import page
  2. def home(request,pid='1'):
  3. data_count = models.Host.objects.count() # 数据总条数
  4. page_obj = page.Page(pid,10,data_count,'/home/',10)
  5. data_list = models.Host.objects.all()[page_obj.start():page_obj.end()] # 返回数据列表
  6. return render(request,'home.html',{'data_list':data_list,'pagestr':page_obj.pagestr})

3 home.html 模板

模板通过 render 函数传过来的参数对模板进行渲染,生成分页信息,注意:Page类中pagestr返回给模板的为字符串信息,需要通过 模板语言的safe 方法来允许模板进行渲染。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Index</title>
  6. <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
  7. </head>
  8. <body>
  9. <div style="width: 800px;margin: 0 auto">
  10. <table class="table table-hover">
  11. <h1>主机列表</h1>
  12. <tr>
  13. <th>ID</th>
  14. <th>主机名</th>
  15. <th>IP</th>
  16. </tr>
  17. {% for obj in data_list %}
  18. <tr>
  19. <td>{{ obj.id }}</td>
  20. <td>{{ obj.hostname }}</td>
  21. <td>{{ obj.ip }}</td>
  22. </tr>
  23. {% endfor %}
  24. </table>
  25. <nav aria-label="...">
  26. <ul class="pagination">
  27. {{ pagestr|safe }}
  28. </ul>
  29. </nav>
  30. </div>
  31. </body>
  32. </html>

4. page.py

这个文件是我放到了最外层目录下的utils文件夹下。

在上面介绍views.py中的home函数时已经说过了函数的具体用法,这里就不在说明了。具体的实现请看下边函数内容。如有不足请指出。

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3.  
  4. class Page(object):
  5. def __init__(self,currout_page,num,data_count,url,page_num):
  6. currout_page = int(currout_page) if currout_page.isdigit() else 1 # 当前页
  7. self.num = num # 每页显示的数据条数
  8. a,b = divmod(data_count,num) # 数据总条数
  9. if b == 0:
  10. self.page_count = a
  11. else:
  12. self.page_count = a + 1
  13. self.currout_page = currout_page if 1<=currout_page<=a else 1
  14. self.url = url
  15. self.page_num = page_num
  16. def start(self):
  17. return (self.currout_page - 1) * self.num
  18. def end(self):
  19. return self.currout_page * self.num
  20. def pagestr(self):
  21. pagestr = []
  22. if self.currout_page > 1:
  23. top = '<li><a href="%s%s">上一页</a></li>'%(self.url,self.currout_page - 1)
  24. pagestr.append(top)
  25. if self.page_count <= self.page_num:
  26. for i in range(1,self.page_count):
  27. range_str = '<li><a href="%s%s">%s</a></li>'%(self.url,i,i)
  28. pagestr.append(range_str)
  29. else:
  30. if self.currout_page <= int(self.page_num/2):
  31. start = 1
  32. end = self.page_num + 1
  33. else:
  34. if self.currout_page < self.page_count - int(self.page_num/2):
  35. start = self.currout_page - int(self.page_num/2)
  36. end = self.currout_page + int(self.page_num/2)
  37. else:
  38. start = self.page_count - self.page_num
  39. end = self.page_count
  40. for i in range(start,end+1):
  41. if i == self.currout_page:
  42. range_str = '<li class="active"><a href="%s%s">%s</a></li>' % (self.url, i, i)
  43. pagestr.append(range_str)
  44. else:
  45. range_str = '<li><a href="%s%s">%s</a></li>'%(self.url,i,i)
  46. pagestr.append(range_str)
  47.  
  48. if self.currout_page < self.page_count:
  49. buttom = '<li><a href="%s%s">下一页</a></li>'%(self.url,self.currout_page + 1)
  50. pagestr.append(buttom)
  51.  
  52. return ''.join(pagestr)

page.py

2 Form

Form 有两个功能,一个是数据验证,一个是可以生成html。

2.1 Form 验证

数据到数据库的流程一般为如下,用户输入数据,提交后台,后台写入,返回结果给前端。没错。

这里就涉及到数据的正确性,数据是否使我们想要的格式,这样一来就需要做判断。。。。。。

前端判断 可以减少错误数据发送到后端,但后端为了保险起见,还要检验下数据是否可用,真麻烦。。。。然而From就可以帮你来验证数据是否可用。

之前的思路是,点击一个button,跳转到一个新的页面,在新的页面中添加并提交数据,数据在前端和后台都进行下验证,然后写入数据库并返回执行结果

but , 现在有了Django的Form验证,一切变得简单。

---------------------------------------------------开始来了解下Form的基本用法-----------------------------------------------------------------------

  1. from django import forms
  2. from django.forms import fields
  3. class HostInfo(forms.Form):
  4. hostname = fields.CharField(
  5. required=True,
  6. error_messages={'required':'hostname不能为空'},
  7. )
  8. ip = fields.GenericIPAddressField(
  9. error_messages={'required': 'IP不能为空','invalid':'IP格式错误'},
  10. )
  11. user_id = fields.IntegerField(
  12. error_messages={'required': 'User_id不能为空'},
  13. )

使用Form需要通过继承forms.Form来定义一个类,调用类中自己定义的来验证数据是否正确

看上边的代码说下Form的基本使用,

  1.继承forms.Form来定义一个类

  2.类中包含需要验证的字段必须和前端传到后端的关键字一样,他是根据关键字来对应的。

  3.如果用户数据的信息有误,Form会给我们返回错误信息,错误信息为英文,如果想修改为中文,需要使用error_messages来重新定义错误信息

Form中的方法:

  1. obj = HostInfo(request.POST)

    定义一个Form类的时候需要传入参数,传入参数为request.POST,这样这个函数就会自动帮你验证用户提交的数据。

  2. obj.is_valid()

    返回bool值,表示传入的数据是否验证成功,成功返回True,失败返回False

  3. obj.cleaned_data()

    如果用户输入数据验证通过,通过cleaned_data函数会把数据以字典的形式返回

  4. obj.errors用户的错误信息

    包含用户验证没有通过的错误信息,可以通过obj.errors['hostname'][0]来获取关于hostname的第一条错误信息。

    

views.py文件内容

  1. def add_host(request):
  2. if request.method == 'GET':
  3. return render(request,'add_host.html')
  4. elif request.method == 'POST':
  5. obj = HostInfo(request.POST)
  6. if obj.is_valid():
  7. print(obj.cleaned_data)
  8. return render(request, 'add_host.html', {'obj': obj})
  9. else:
  10. print(obj.errors)
  11. return render(request,'add_host.html',{'obj':obj})

views.py

add_host.html文件内容

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Index</title>
  6. <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
  7. </head>
  8. <body>
  9. <div style="width: 800px;margin: 0 auto">
  10. <form method="post" action="/add_host/">
  11. {% csrf_token %}
  12. <div class="form-group">
  13. <label>Hostname</label>
  14. <input type="text" class="form-control" placeholder="Hostname" name="hostname">
  15. {{ obj.errors.hostname.0 }}
  16. </div>
  17. <div class="form-group">
  18. <label>IP</label>
  19. <input type="text" class="form-control" placeholder="IP" name="ip">
  20. {{ obj.errors.ip.0 }}
  21. </div>
  22. <div class="form-group">
  23. <label>User</label>
  24. <select name="user_id" id="user" class="form-control">
  25. <option value="1">app-01</option>
  26. <option value="2">app-02</option>
  27. <option value="3">app-03</option>
  28. </select>
  29. {{ obj.errors.user_id.0 }}
  30. </div>
  31. <button type="submit" class="btn btn-default">提交</button>
  32. </form>
  33. </div>
  34. </body>
  35. </html>

add_host.html

上边这个版本的问题是无法保留用户上次的数据信息,原因是以为每次都是刷新页面,但并没有将用户数据的信息进行重新传值给模板

当然也可以自己来写,但是Form除了验证功能还有一个功能是用户生成HTML。利用Form的这个功能可以实现把用户输入的数据保留下来,并且渲染传给前端

2.2 Form 生成html

这里的代码是对添加信息做了用户输入信息的验证和错误提示,

views.py文件内容

  1. from django.shortcuts import render
  2. from django.shortcuts import HttpResponse
  3. from django.shortcuts import redirect
  4.  
  5. from app import models
  6. # Create your views here.
  7. def create(request):
  8. models.User.objects.create(username='helei',password='')
  9. models.User.objects.create(username='alex',password='')
  10. models.User.objects.create(username='egon',password='')
  11. for i in range(1,201):
  12. models.Host.objects.create(hostname='www.%s.com'%i,ip='192.168.1.%s'%i,user_id=1)
  13. return HttpResponse('添加成功')
  14.  
  15. # django模块实现分页
  16. from django.core.paginator import Paginator
  17. def index(request,pid=1):
  18. obj_list = models.Host.objects.all() # 所有的数据对象
  19. page_obj = Paginator(obj_list,10) # 定义一个分页对象实例
  20. pages = page_obj.page(pid) # 传递页数给page_obj对象
  21. return render(request,'index.html',{'pages':pages}) # pages.object_list 分页后的数据
  22.  
  23. # 自定义分页函数
  24. from utils import page
  25. def home(request,pid=''):
  26. data_count = models.Host.objects.count() # 数据总条数
  27. page_obj = page.Page(pid,10,data_count,'/home/',10)
  28. data_list = models.Host.objects.all()[page_obj.start():page_obj.end()] # 返回数据列表
  29. return render(request,'home.html',{'data_list':data_list,'pagestr':page_obj.pagestr})
  30.  
  31. from django import forms
  32. from django.forms import fields
  33. from django.forms import widgets
  34. class HostInfo(forms.Form):
  35. hostname = fields.CharField(
  36. required=True, # 设置为非空,默认非空
  37. error_messages={'required':'hostname不能为空'}, # 定义错误提示
  38. widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'用户名'}) # 定义生成的html类型及样式
  39. )
  40. ip = fields.GenericIPAddressField(
  41. error_messages={'required': 'IP不能为空','invalid':'IP格式错误'},
  42. widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'密码'})
  43. )
  44. user_id = fields.IntegerField(
  45. error_messages={'required': 'User_id不能为空'},
  46. widget=widgets.Select(attrs={'class': 'form-control'},choices=[(1,'app-01'),(2,'app-02'),(3,'app-03')])
  47. )
  48. def add_host(request):
  49. if request.method == 'GET':
  50. obj = HostInfo()
  51. return render(request, 'add_host.html', {'obj': obj})
  52. elif request.method == 'POST':
  53. obj = HostInfo(request.POST)
  54. if obj.is_valid():
  55. # 操作数据等其他操作
  56. print('数据验证通过')
  57. else:
  58. print('数据错误')
  59. return render(request,'add_host.html',{'obj':obj})

views.py

add_host.html文件内容

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Index</title>
  6. <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
  7. </head>
  8. <body>
  9. <div style="width: 800px;margin: 0 auto">
  10. <form method="post" action="/add_host/" novalidate>
  11. {% csrf_token %}
  12. <div class="form-group">
  13. <label>Hostname</label>
  14. {{ obj.hostname }}
  15. {{ obj.errors.hostname.0 }}
  16. </div>
  17. <div class="form-group">
  18. <label>IP</label>
  19. {{ obj.ip }}
  20. {{ obj.errors.ip.0 }}
  21. </div>
  22. <div class="form-group">
  23. <label>User</label>
  24. {{ obj.user_id }}
  25. {{ obj.errors.user_id.0 }}
  26. </div>
  27. <button type="submit" class="btn btn-default">提交</button>
  28. </form>
  29. </div>
  30. </body>
  31. </html>

add_host.html

结合对数据库的操作来看看添加的数据是否成功:(上面代码中有些中文写错了。  主要点,下面这个都改好了。)

views.py文件内容

  1. from django.shortcuts import render
  2. from django.shortcuts import HttpResponse
  3. from django.shortcuts import redirect
  4.  
  5. from app import models
  6. # Create your views here.
  7. def create(request):
  8. models.User.objects.create(username='helei',password='')
  9. models.User.objects.create(username='alex',password='')
  10. models.User.objects.create(username='egon',password='')
  11. for i in range(1,201):
  12. models.Host.objects.create(hostname='www.%s.com'%i,ip='192.168.1.%s'%i,user_id=1)
  13. return HttpResponse('添加成功')
  14.  
  15. # django模块实现分页
  16. from django.core.paginator import Paginator
  17. def index(request,pid=1):
  18. obj_list = models.Host.objects.all() # 所有的数据对象
  19. page_obj = Paginator(obj_list,10) # 定义一个分页对象实例
  20. pages = page_obj.page(pid) # 传递页数给page_obj对象
  21. return render(request,'index.html',{'pages':pages}) # pages.object_list 分页后的数据
  22.  
  23. # 自定义分页函数
  24. from utils import page
  25. def home(request,pid=''):
  26. data_count = models.Host.objects.count() # 数据总条数
  27. page_obj = page.Page(pid,10,data_count,'/home/',10)
  28. data_list = models.Host.objects.all().select_related().order_by('-id')[page_obj.start():page_obj.end()] # 返回数据列表
  29. return render(request,'home.html',{'data_list':data_list,'pagestr':page_obj.pagestr})
  30.  
  31. from django import forms
  32. from django.forms import fields
  33. from django.forms import widgets
  34. class HostInfo(forms.Form):
  35. hostname = fields.CharField(
  36. required=True, # 设置为非空,默认非空
  37. error_messages={'required':'hostname不能为空'}, # 定义错误提示
  38. widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'主机名'}) # 定义生成的html类型及样式
  39. )
  40. ip = fields.GenericIPAddressField(
  41. error_messages={'required': 'IP不能为空','invalid':'IP格式错误'},
  42. widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'IP地址'})
  43. )
  44. user_id = fields.IntegerField(
  45. error_messages={'required': 'User_id不能为空'},
  46. widget=widgets.Select(attrs={'class': 'form-control'},
  47. choices=[(1,'app-01'),(2,'app-02'),(3,'app-03')])
  48. )
  49. def __init__(self,*args,**kwargs):
  50. super(HostInfo,self).__init__(*args,**kwargs)
  51. self.fields['user_id'].widget.choices = models.User.objects.values_list('id', 'username')
  52. def add_host(request):
  53. if request.method == 'GET':
  54. obj = HostInfo()
  55. return render(request, 'add_host.html', {'obj': obj})
  56. elif request.method == 'POST':
  57. obj = HostInfo(request.POST)
  58. if obj.is_valid():
  59. # 操作数据等其他操作
  60. ret = models.Host.objects.create(**obj.cleaned_data)
  61. print('数据验证通过')
  62. return redirect('/home/')
  63. else:
  64. print('数据错误')
  65. return render(request,'add_host.html',{'obj':obj})

views.py

add_host.html文件内容

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Index</title>
  6. <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
  7. </head>
  8. <body>
  9. <div style="width: 800px;margin: 0 auto">
  10. <form method="post" action="/add_host/" novalidate>
  11. {% csrf_token %}
  12. <div class="form-group">
  13. <label>Hostname</label>
  14. {{ obj.hostname }}
  15. {{ obj.errors.hostname.0 }}
  16. </div>
  17. <div class="form-group">
  18. <label>IP</label>
  19. {{ obj.ip }}
  20. {{ obj.errors.ip.0 }}
  21. </div>
  22. <div class="form-group">
  23. <label>User</label>
  24. {{ obj.user_id }}
  25. {{ obj.errors.user_id.0 }}
  26. </div>
  27. <button type="submit" class="btn btn-default">提交</button>
  28. </form>
  29. </div>
  30. </body>
  31. </html>

add_host.html

    在user_id中widget=widgets.Select() 可以设置为下拉框,内有两个参数,attrs为设置下拉框的样式设置,choices是这是下拉框的默认参数,

  如果设置为  choices = models.User.objects.values_list('id', 'username')

  需要注意的是这里的默认设置只在程序运行的时候加载一次,如果与user_id关联的外键表数据有改变, 在添加页面的下拉框中内容时不会实时变化的。可以使用下列方法解决这个问题。

  1. def __init__(self,*args,**kwargs):
    super(HostInfo,self).__init__(*args,**kwargs)
    self.fields['user_id'].widget.choices = models.User.objects.values_list('id', 'username')
    # 通过重写重写父类的构造函数,使类在每次调用的时候都去数据库取值进行赋值加载

到这里,这个添加功能就算是写完了, 下面写下编辑的功能

  1. """test_s18 URL Configuration
  2.  
  3. The `urlpatterns` list routes URLs to views. For more information please see:
  4. https://docs.djangoproject.com/en/1.11/topics/http/urls/
  5. Examples:
  6. Function views
  7. 1. Add an import: from my_app import views
  8. 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
  9. Class-based views
  10. 1. Add an import: from other_app.views import Home
  11. 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
  12. Including another URLconf
  13. 1. Import the include() function: from django.conf.urls import url, include
  14. 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
  15. """
  16. from django.conf.urls import url
  17. from django.contrib import admin
  18. from app import views
  19. urlpatterns = [
  20. url(r'^admin/', admin.site.urls),
  21. url(r'^create/$', views.create),
  22. url(r'^index/$', views.index),
  23. url(r'^index/(?P<pid>\d+)$', views.index),
  24. url(r'^home/$', views.home), # 自定义分页专用
  25. url(r'^home/(?P<pid>\d+)$', views.home), # 自定义分页专用
  26. url(r'^add_host/',views.add_host),
  27. url(r'^edit_host/(?P<hid>\d+)$',views.edit_host),
  28. ]

urls.py

  1. from django.shortcuts import render
  2. from django.shortcuts import HttpResponse
  3. from django.shortcuts import redirect
  4.  
  5. from app import models
  6. # Create your views here.
  7. def create(request):
  8. models.User.objects.create(username='helei',password='')
  9. models.User.objects.create(username='alex',password='')
  10. models.User.objects.create(username='egon',password='')
  11. for i in range(1,201):
  12. models.Host.objects.create(hostname='www.%s.com'%i,ip='192.168.1.%s'%i,user_id=1)
  13. return HttpResponse('添加成功')
  14.  
  15. # django模块实现分页
  16. from django.core.paginator import Paginator
  17. def index(request,pid=1):
  18. obj_list = models.Host.objects.all() # 所有的数据对象
  19. page_obj = Paginator(obj_list,10) # 定义一个分页对象实例
  20. pages = page_obj.page(pid) # 传递页数给page_obj对象
  21. return render(request,'index.html',{'pages':pages}) # pages.object_list 分页后的数据
  22.  
  23. # 自定义分页函数
  24. from utils import page
  25. def home(request,pid=''):
  26. data_count = models.Host.objects.count() # 数据总条数
  27. page_obj = page.Page(pid,10,data_count,'/home/',10)
  28. data_list = models.Host.objects.all().select_related().order_by('-id')[page_obj.start():page_obj.end()] # 返回数据列表
  29. return render(request,'home.html',{'data_list':data_list,'pagestr':page_obj.pagestr})
  30.  
  31. from django import forms
  32. from django.forms import fields
  33. from django.forms import widgets
  34. class HostInfo(forms.Form):
  35. hostname = fields.CharField(
  36. required=True, # 设置为非空,默认非空
  37. error_messages={'required':'hostname不能为空'}, # 定义错误提示
  38. widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'主机名'}) # 定义生成的html类型及样式
  39. )
  40. ip = fields.GenericIPAddressField(
  41. error_messages={'required': 'IP不能为空','invalid':'IP格式错误'},
  42. widget=widgets.TextInput(attrs={'class':'form-control','placeholder':'IP地址'})
  43. )
  44. user_id = fields.IntegerField(
  45. error_messages={'required': 'User_id不能为空'},
  46. widget=widgets.Select(attrs={'class': 'form-control'},
  47. choices=[(1,'app-01'),(2,'app-02'),(3,'app-03')])
  48. )
  49. def __init__(self,*args,**kwargs):
  50. super(HostInfo,self).__init__(*args,**kwargs)
  51. self.fields['user_id'].widget.choices = models.User.objects.values_list('id', 'username')
  52. def add_host(request):
  53. if request.method == 'GET':
  54. obj = HostInfo()
  55. return render(request, 'add_host.html', {'obj': obj})
  56. elif request.method == 'POST':
  57. obj = HostInfo(request.POST)
  58. if obj.is_valid():
  59. # 操作数据等其他操作
  60. print('数据验证通过')
  61. ret = models.Host.objects.create(**obj.cleaned_data)
  62. if ret:
  63. print('添加数据成功')
  64. else:
  65. print('添加数据失败') # 后期需要改进
  66. return redirect('/home/')
  67. else:
  68. print('数据错误')
  69. return render(request,'add_host.html',{'obj':obj})
  70.  
  71. def edit_host(request,hid):
  72. if request.method == 'GET':
  73. userinfo = models.Host.objects.filter(id=hid).values('hostname','ip','user_id').first()
  74. obj=HostInfo(initial=userinfo) # 利用initial给HostInfo 赋值
  75. print(obj)
  76. return render(request,'edit_host.html',{'obj':obj})
  77. elif request.method == 'POST':
  78. obj = HostInfo(request.POST)
  79. if obj.is_valid():
  80. # 操作数据等其他操作
  81. print('数据验证通过')
  82. ret = models.Host.objects.filter(id=hid).update(**obj.cleaned_data)
  83. if ret:
  84. print('编辑数据成功')
  85. else:
  86. print('编辑数据失败') # 后期需要改进
  87. return redirect('/home/')
  88. else:
  89. print('数据错误')
  90. return render(request,'add_host.html',{'obj':obj})

views.py

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Index</title>
  6. <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
  7. </head>
  8. <body>
  9. <div style="width: 800px;margin: 0 auto">
  10. <form method="post">
  11. {% csrf_token %}
  12. <div class="form-group">
  13. <label>Hostname</label>
  14. {{ obj.hostname }}
  15. {{ obj.errors.hostname.0 }}
  16. </div>
  17. <div class="form-group">
  18. <label>IP</label>
  19. {{ obj.ip }}
  20. {{ obj.errors.ip.0 }}
  21. </div>
  22. <div class="form-group">
  23. <label>用户</label>
  24. {{ obj.user_id }}
  25. {{ obj.errors.user_id.0 }}
  26. </div>
  27. <button type="submit" class="btn btn-default">提交</button>
  28. </form>
  29. </div>
  30. </body>
  31. </html>

edit_host.py

字段类型:

  1. fields字段类型:
  2. CharFiled()
  3. EmailField()
  4. IntegerField()
  5. GenericIPAddressField()
  6. FileField() # 上传文件的
  7.  
  8. fields.RegexField(
  9. regex='\d+'
  10. ) # 自定义
  11.  
  12. fields.ChoiceField() # 多选

字段中插件类型:

  1. widgets插件
  2.  
  3. widgets.TextInput()
       widgets.FileInput()
  4. widgets.TextPasswordInput()
  5. widgets.Textarea()
  6. widgets.Select()
  7. widgets.SelectMultiple()
      widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
      http://www.cnblogs.com/wupeiqi/articles/6144178.html

http://www.cnblogs.com/wupeiqi/articles/6144178.html

3.中间件

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. from django.utils.deprecation import MiddlewareMixin
  4. from django.shortcuts import HttpResponse
  5. class M1(MiddlewareMixin):
  6. def process_request(self,request):
  7. print('m1')
  8. def process_view(self, request, callback, callback_args, callback_kwargs):
  9. print('m1.process_view')
  10. def process_exception(self, request, exception):
  11. return HttpResponse('我给处理了')
  12. def process_response(self,request,response):
  13. print(response)
  14. print('m2')
  15. return response

http://www.cnblogs.com/wupeiqi/articles/5237704.html

待续中间件

Python Django的分页,Form验证,中间件的更多相关文章

  1. day18 分页+form验证+中间件

    参考课件: http://www.cnblogs.com/wupeiqi/articles/6144178.html http://www.cnblogs.com/wupeiqi/articles/5 ...

  2. python自动化开发-[第二十一天]-form验证,中间件,缓存,信号,admin后台

    今日概要: 1.form表单进阶 2.中间件 3.缓存 4.信号 5.admin后台 上节课回顾 FBV,CBV 序列化 - Django内置 - json.dumps(xxx,cls=) Form验 ...

  3. Python - Django - 简单分页的实现

    models.py: from django.db import models class Book(models.Model): title = models.CharField(max_lengt ...

  4. Python - Django - 封装分页成通用的模块

    新建 utils 文件夹,并创建 page.py page.py: class ShowPage(object): def __init__(self, page_num, total_count, ...

  5. Django进阶之Form

    Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 一.创建Form类 #!/usr/bin/en ...

  6. Python Django缓存,信号,序列化,文件上传,Ajax登录和csrf_token验证

    本节内容 models操作 Django的缓存 请求方式 序列化 Form 配合Ajax实现登录认证 上传文件 Ajax  csrf_token验证方式 1 models操作 单表查询: curd(增 ...

  7. tornado web高级开发项目之抽屉官网的页面登陆验证、form验证、点赞、评论、文章分页处理、发送邮箱验证码、登陆验证码、注册、发布文章、上传图片

    本博文将一步步带领你实现抽屉官网的各种功能:包括登陆.注册.发送邮箱验证码.登陆验证码.页面登陆验证.发布文章.上传图片.form验证.点赞.评论.文章分页处理以及基于tornado的后端和ajax的 ...

  8. python运维开发(十九)----Django后台表单验证、session、cookie、model操作

    内容目录: Django后台表单验证 CSRF加密传输 session.cookie model数据库操作 Django后台Form表单验证 Django中Form一般有2种功能: 1.用于做用户提交 ...

  9. python Django之Form组件

    python Django之Form组件 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试 ...

随机推荐

  1. 07-TypeScript的For循环

    在传统的JavaScript中,关于循环,可以有两种方式,一种是forEach,一种是for. forEach的用法如下: var sarr=[1,2,3,4]; sarr.desc="he ...

  2. STM32F4系列单片机上使用CUBE配置MBEDTLS实现pem格式公钥导入

    |版权声明:本文为博主原创文章,未经博主允许不得转载. 最近尝试在STM32F4下用MBEDTLS实现了公钥导入(我使用的是ECC加密),整个过程使用起来比较简单. 首先,STM32F4系列CUBE里 ...

  3. 创建帧动画1 - xml方式

    废话不多说,先看东西   创建帧动画1 - xml方式 帧动画的创建方式主要以下2种: * 用xml创建动画: * 用代码创建动画:   本文内容主要关注 xml文件 创建帧动画的方式   xml文件 ...

  4. api-gateway实践(04)新服务网关 - 新手入门

    一.网关引擎环境 1.下载代码 2.搭建环境 3.打包部署 二.配置中心环境 1.下载代码 2.搭建环境 3.打包部署 三.创建业务实例 1.以租户身份登录配置中心,注册 group.version. ...

  5. 实现GridControl的行单元格非顺序跳转

    用GridControl控件添加数据的时候发现,有一些字段过多但是并不是每个字段都需要用户输入,每个单元格都回车跳转的时候不仅浪费时间,而且用户体验也不好,就需要单元格跳转的时候,不需要的字段可以隔过 ...

  6. centOs6.5配置jdk及其注意事项

    1.下载jdk1.7 百度云链接: https://pan.baidu.com/s/15vXLO2eV18eVvmt-R5jGnQ 密码: 1gd6 2.解压压缩包 通过终端在/usr/local下新 ...

  7. 十个你需要在 PHP 7 中避免的坑

    1. 不要使用 mysql_ 类函数 终于,你不用再看到建议不要使用 mysql_ 函数的提示了.因为 PHP 7 从核心上完全移除了它们,这意味着请你移步至更好的 mysqli_ 类函数,或者更灵活 ...

  8. python-3.x-基本数据类型

    当前学习版本为: python-3.6-4 代码: """整型 NUMBER""" a = 2 ** 5 b = a + 4 c = a / ...

  9. [LuoguP1113] 杂物 - 拓扑排序

    其实只是纪念下第一篇洛谷题解? Description John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它.比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及 ...

  10. hive:默认允许动态分区个数为100,超出抛出异常:

    在创建好一个分区表后,执行动态分区插入数据,抛出了错误: Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: [Erro ...