Django 从0开始创建一个项目
title: Django 从0开始创建一个项目
tags: Django
---
Django 从0开始创建一个项目
创建Django工程及配置
创建工程:
django-admin starproject 项目名
创建APP:
Python3 manage.py startapp app名称
可以创建多个app,每个app代表不同的业务,开发的时候互不影响- URL通过路由分发实现跳转
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', 'app02', 'app03', ]
配置模板路径:
'DIRS': [os.path.join(BASE_DIR, 'templates')],
配置静态文件路径:
STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
- 注释配置文件的一行:
'django.middleware.csrf.CsrfViewMiddleware',
这个不注释POST请求拿不到数据
Django的目录结构:
|--mysite01 |---|app01 |----------|migrations | |admin.py | |apps.py | |models.py | |tests.py | |views.py |mysite01 |--------|__init__.py | |settings.py | |urls.py | |wsgi.py | |templates | |manage.py
- migrations 存放有关数据库的文件,保存数据库的修改信息 - admin Django自己的后台管理 - models 通过ORM用类创建数据库和表 - tests 单元测试 - views 视图函数,业务处理,可以继续进行分类,此时就是views文件夹 - apps app的配置文件 - /mysite01/mysite01/__init__.py 配置数据库,默认是sqllite,这里配置成mysql,通过pymysql连接数据库 import pymysql pymysql.install_as_MySQLdb() -urls 路由系统 - wsgi web服务
路由系统:
URL-函数 的对应关系
/login/
一一对应 静态路由/add-user/(\d+)
支持正则 动态路由/add-user/(\d+).html
伪静态
具体实现
- 第一步是在urls中导入视图函数
from app01 import views
设置URL:
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^edit/(\w+)/', views.edit), # 通过正则匹配路径 ]
- 编写视图函数:
把URL变美观 ,视图函数要有参数接收
def edit(request,arg):
from django.shortcuts import render, HttpResponse, redirect def index(request): user_list = [ 'aaa', 'bbb', 'ccc', ] return render(request, 'index.html', {'user_list': user_list}) def edit(request, a1): print(a1) # 接收函数URL的参数 return HttpResponse("ok")
- 编写index.html,关键是以
/
结尾
<ul> {% for i in user_list %} <li>{{ i }}| <a href="/edit/{{ i }}/">编辑</a></li> {% endfor %} </ul>
总结:
- 在函数中通过参数a1接收url
- 点击的标签上添加路径结尾要用
/
url(r'^edit/(\w+)/', views.edit),
通常这里是以/
结尾的
正则匹配
- 按照位置传值(有先后顺序)
url(r'^edit/(\w+)/(\w+)/', views.edit), def edit(request, a1, a2): print(a1, a2) # 接收函数URL的参数 return HttpResponse("ok")
- 按照名称(关键字)(?P\w+) 注意是在正则表达式的括号里面传参数
- 可以没有顺序,这个过程相当于找到相应的参数名进行赋值
url(r'^edit/(?P<a1>\w+)/(?P<a2>\w+)/', views.edit), def edit(request, a1, a2): return HttpResponse("ok")
注意:这两种是不能混合使用的,必须是统一的形式,这样才能用
*args, **kwargs.
要主要下面的情况是,*args用来接收按位置传值,**kwargs用来接收按关键字传值的
def edit(request, *args, **kwargs): return HttpResponse("ok")
- 规定路由的结尾
推荐用终止符$
^edit$ 伪静态(SEO)
url(r'^edit/(\w+)'.html$, views.edit),
404页面,默认页面
用户输错的时候返回404页面,或者是默认的主页
url(r'^', views.index),
前面的正则是不加内容的,后面写函数名
路由分发(涉及多个app的时候)
在处理不同业务的时候,多个app
引入include
- mysite下面的总的路由
from django.conf.urls import url, include # 在这里引入include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/', include('app01.urls')), # 先匹配app01,然后找app01下面的url url(r'^app02/', include('app02.urls')), ]
- app01的路由
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^index/', views.index), ]
- app02子路由
from django.conf.urls import url from django.contrib import admin from app02 import views urlpatterns = [ url(r'^index/', views.index), ]
url 关系命名
通过刚给URL设置别名,可以通过别名反向获取URL
url(r'^index,views.index,name =n1)
在index函数中就可以通过'n1'获取路径
from django.urls import reverse v = reverse('n1') print(v)
还可以自己定义,返回的路径名
根据名字反生成URL
name reverse
URL的后缀可以自己任意定义
- 通过位置参数传值
url(r'^index/(\w+)/', views.index, name='n1'), def index(request, a1): # 这里需要接受参数 user_list = [ 'aaa', 'bbb', 'ccc', ] v = reverse('n1', args=(1,)) # 这里是等号,里面的参数可以是任意值 print(v) return render(request, 'index.html', {'user_list': user_list})
- 通过关键字
url(r'^index/(?P<a1>\w+)/', views.index, name='n1'), def index(request, a1): # 接收参数 user_list = [ 'aaa', 'bbb', 'ccc', ] # v = reverse('n1', args=(1,)) v = reverse('n1', kwargs={'a1': 123}) # 这里是按照关键字,形式是字典 print(v) return render(request, 'index.html', {'user_list': user_list})
应用:
{% url “m1” %} {% url “m1” "m2" %}
- 在模板中的form表单中不用action写具体的路径,直接获取路径
url(r'^login/', views.login, name='m1'), def login(request): return render(request, 'login.html')
注意的是'm1' 要加引号
<form method="POST" action="{% url "m1" %}"> <input type="text"> </form>
- 在跳转路径的时候
url(r'^index/', views.index, name='n1'), url(r'^edit/(\w+)/', views.edit, name='n2'),
下面的
url "n2"接收URL ,i是拼接的路径,后面还可以添加 用空格分割
<ul> {% for i in user_list %} <!-- <li>{{ i }}| <a href="/edit/{{ i }}/">编辑</a></li> --> <li>{{ i }}| <a href="{% url "n2" i %}/">编辑</a></li> {% endfor %} </ul>
别名是用于权限管理
- 前端处理 在模板中通过别名反向获取
- Python处理
视图函数 CBV(class based view) FBV(function based view)
CBV是URL对应类,FBV是URL对应函数
from表单提交
get 查
post 创建
View 下面的常用方法,实现增删改查可以进入View中查看 除post get外都是ajax的方法
"""
get 查
post 创建
put 更新
delete 删除
"""
通过Class来获取get和post的数据,具体的实现方法是继承了View类中的dispath中的handle方法,handle通过把获取的GET/POST转换成小写,然后返回函数并执行
if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
具体实现
url
CBV用类的方法as_view(),返回值是一个函数,在这里是get/post
url(r'^login.html$',views.Login.as_view()),
类
注意下面注释中的三点
1 导入View
2 继承View
3 request 获取全部的内容
from django.views import View # 需要导入 class Login(View): # 继承View """ get 查 post 创建 put 更新 delete 删除 """ def get(self, request): # 还要有参数request return render(request, 'login.html') def post(self, request): user = request.POST.get('user') # 从前端的post发送的内容中获取数据 print(user) return HttpResponse('login.post')
login的前端
<form method="POST" action="/login.html"> <input type="text" name="user"> <input type="submit" value="提交"> </form>
自己重写dispath方法
内部是通过反射getattr具体是dispatch函数
关键点:
1 super继承
2 返回值
3 前后加上相应的操作(批量操作),实现了装饰器的功能
class Login(View): def dispath(self,request,*args,**kwargs): print("before") obj = super(Login, self).dispath(request,*args,**kwargs) # 通过super继承父类的方法 print('after') return obj # 返回值就是执行相应的函数 def get(self, request): return render(request, 'login.html') def post(self, request): user = request.POST.get('user') print(user) return HttpResponse('login.post')
在models中使用反射
修改类的
__str__
1
class UserType(models.Model): """ 用户类型 """ title = models.CharField(max_length=32) def __str__(self): return "%s-%s" %(self.id,self.title) # 直接通过点就可以
v= models.UserType.objects.all().first() v= models.UserType.objects.all() print(v)
2
class UserInfo(models.Model): """ 用户表 """ name = models.CharField(max_length=16) age = models.IntegerField() ut = models.ForeignKey('UserType') def __str__(self): return "%s-%s-%s-%s" %(self.id,self.name,self.age,self.ut)
obj = models.UserType.objects.all().first() # 这样获得是对象 all()获得是Queryset对象 result = obj.userinfo_set.all() # print(result) "<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>" for i in result: print(i)
结果:
1-用户1-19-1-普通用户 3-蛋子-19-1-普通用户 4-钢弹-19-1-普通用户
Django的ORM操作
http请求
URL-视图(模板+数据)
ORM利用pymysql第三方连接数据库
Django默认的是MySQLDB,需要修改成pymysql
Django默认
ORM 操作表
Django自己有ORM框架,类-表,对象-行
其他的框架自己用pymysql和SqlAchemy
- 创建表
- 修改表(SQLAchemery不能修改表)
- 删除表
1 创建数据库
2 django默认的数据库是SQLlite,修改配置文件,设置连接的数据库为MySQL
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'dataname', # 数据库名 'USER': 'root', 'PASSWORD': '', 'HOST': 'localhost', 'PORT': 3306, } }
3 替换MySQLDB,通过pymysql连接数据库
在工程的
__init__中添加
import pymysql pymysql.install_as_MySQLdb()
ORM操作数据行
在models中创建类
创建user_info表,默认id自动生成,注意数据长度
from django.db import models class UserInfo(models.Model): nid = models.BigAutoField(primary_key=True) # 不写默认生成id列 user = models.CharField(max_length=32) password = models.CharField(max_length=64)
注册app
在settings中的添加
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', 'app02', 'app03', ]
创建表的命令
python3 manage.py makemigrations
python3 manage.py migrate
D:\mysite01>python3 manage.py makemigrations Migrations for 'app01': app01\migrations\0001_initial.py - Create model UserInfo D:\mysite01>python3 manage.py migrate Operations to perform: Apply all migrations: admin, app01, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying app01.0001_initial... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying sessions.0001_initial... OK
最后生成的表的名字是app01_userifo
修改表的列名
在类中直接修改,然后执行创建表的命令。
数据库的修改的内容都保存在migrations文件中,修改前会先读取,然后就行修改
输入y确认修改
D:\mysite01>python3 manage.py makemigrations Did you rename userinfo.password to userinfo.pwd (a CharField)? [y/N] y Migrations for 'app01': app01\migrations\0004_auto_20170624_2021.py - Rename field password on userinfo to pwd D:\mysite01>python3 manage.py migrate Operations to perform: Apply all migrations: admin, app01, auth, contenttypes, sessions Running migrations: Applying app01.0004_auto_20170624_2021... OK
数据表增加
注意的是是否为空,有两种方案
设置为空
age = models.IntegerField(null=True)
设置默认值
age = models.IntegerField(default=1)
创建外键关系
新建usergroup表,然后在userinfo表中增加一列外键关系表
ug = models.ForeignKey('UserGroup',null=True)
- 设置默认为空
- 最终生成的外键的名字是
ug_id
数据行增删改查操作
增加一行数据
from app01 import models def index(request): models.UserGroup.objects.create(title="技术部") return HttpResponse("...")
导入多条数据
外键用ug_id,添加前要有外键的数据
models.UserInfo.objects.create(user='abc', pwd='123', age=18, ug_id=1)
查看数据
group_list = models.UserGroup.objects.all() print(group_list) QuerySet [<UserGroup: UserGroup object>, <UserGroup: UserGroup object>]
得到的结果是一个QuerySet对象,可以看做一个列表,列表中的每一个对象代表一行数据
- 在后台查看数据
def index(request): group_list = models.UserGroup.objects.all() print(group_list) for row in group_list: print(row.id, row.title) return HttpResponse("...")
- 在前端模板中查看数据
<ul> {% for row in user_list %} <li>{{ row.nid }} | {{row.user }} | {{ row.pwd }} | {{ row.age }}</li> {% endfor %} </ul>
结果:
1 | abc | 123 | 18
2 | abc | 123 | 18
查看数据的范围filter
使用了双下划线
user_list = models.UserInfo.objects.filter(nid=1) user_list = models.UserInfo.objects.filter(nid__gt=1) # nid 大于1的数据 user_list = models.UserInfo.objects.filter(nid__lt=2) # nid 小于2的数据
删除数据
注意有外键的不能删除
models.UserInfo.objects.filter(nid=3).delete()
更新数据
models.UserGroup.objects.filter(id=2).update(title="新的部门")
连表操作
和SQLAchemy类似
对象可以跨表
在循环的时候跨表
拿一个的时候是obj
all 是QerySet[obj,obj]
filterQerySet[obj,obj]
正向操作
1 all()使用点
通过UserInfo 的ut(外键)连表UserType
v = models.UserInfo.objects.all().first() # 用first进行试验 print(v.ut.id,v.ut.title) # 使用点能点出方法
2 values() 使用双下划线进行跨表
返回值是字典
v2 = models.UserInfo.objects.values('id','name','age','ut__id','ut__title') for i in v2: print(i) """ {'id': 1, 'name': '用户1', 'age': 19, 'ut__id': 1, 'ut__title': '普通用户'} {'id': 2, 'name': '用户2', 'age': 19, 'ut__id': 2, 'ut__title': '超级用户'} {'id': 3, 'name': '蛋子', 'age': 19, 'ut__id': 1, 'ut__title': '普通用户'} {'id': 4, 'name': '钢弹', 'age': 19, 'ut__id': 1, 'ut__title': '普通用户'} {'id': 5, 'name': '钢珠', 'age': 19, 'ut__id': 3, 'ut__title': '白金用户'} """
3 value_list()
values_lis也是用双下划线
返回值是元组
v2 = models.UserInfo.objects.values_list('id','name','age','ut__id','ut__title') for i in v2: print(i) (1, '用户1', 19, 1, '普通用户') (2, '用户2', 19, 2, '超级用户') (3, '蛋子', 19, 1, '普通用户') (4, '钢弹', 19, 1, '普通用户') (5, '钢珠', 19, 3, '白金用户')
反向操作
1 小写的表名_set
下面是通过all().first()获取第一个对象。只能通过对象进行反向操作userinfo_set.all()
obj = models.UserType.objects.all().first() # 这样获得是对象 all()获得是Queryset对象 result = obj.userinfo_set.all() # 只能是通过对象进行操作 print(result) "<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>" for i in result: print(i) 下面是通过反射获得的: 1-用户1-19-1-普通用户 3-蛋子-19-1-普通用户 4-钢弹-19-1-普通用户
2 values
返回的是字典
v = models.UserType.objects.values('id','title','userinfo') for i in v: print(i)
结果:
{'id': 1, 'title': '普通用户', 'userinfo': 1} {'id': 1, 'title': '普通用户', 'userinfo': 3} {'id': 1, 'title': '普通用户', 'userinfo': 4} {'id': 2, 'title': '超级用户', 'userinfo': 2} {'id': 3, 'title': '白金用户', 'userinfo': 5}
v = models.UserType.objects.values('id', 'title', 'userinfo__id','userinfo__name','userinfo__age') for i in v: print(i)
结果:
{'id': 1, 'title': '普通用户', 'userinfo__id': 1, 'userinfo__name': '用户1', 'userinfo__age': 19} {'id': 1, 'title': '普通用户', 'userinfo__id': 3, 'userinfo__name': '蛋子', 'userinfo__age': 19} {'id': 1, 'title': '普通用户', 'userinfo__id': 4, 'userinfo__name': '钢弹', 'userinfo__age': 19} {'id': 2, 'title': '超级用户', 'userinfo__id': 2, 'userinfo__name': '用户2', 'userinfo__age': 19} {'id': 3, 'title': '白金用户', 'userinfo__id': 5, 'userinfo__name': '钢珠', 'userinfo__age': 19}
3 values_list
values_list返回的是元组对象
用filter进行跨表
正向操作
v=models.UserInfo.objects.filter(ut__title='普通用户').values('id','name','ut__title') # print(v) for i in v: print(i)
结果:
{'id': 1, 'name': '用户1', 'ut__title': '普通用户'} {'id': 3, 'name': '蛋子', 'ut__title': '普通用户'} {'id': 4, 'name': '钢弹', 'ut__title': '普通用户'}
反向操作
A.onjects.filter(b__id=xx 或 b__age=xx 或 b__name=)
下面测试的是age=19的用户
v=models.UserType.objects.filter(userinfo__age=19).values('id','title','userinfo__name') print(v) for i in v: print(i)
结果:
{'id': 1, 'title': '普通用户', 'userinfo__name': '用户1'} {'id': 2, 'title': '超级用户', 'userinfo__name': '用户2'} {'id': 1, 'title': '普通用户', 'userinfo__name': '蛋子'} {'id': 1, 'title': '普通用户', 'userinfo__name': '钢弹'} {'id': 3, 'title': '白金用户', 'userinfo__name': '钢珠'}
Django分页
分页的目的是:在数据量太大分批获取数据并在页面上进行展示
简单的操作就是通过切片获取
user_list = models.UserInfo.objects.all()[1:10] user_list = models.UserInfo.objects.all()[10:20]
Django自带分页
适合做上下页,只能在Django中用
分页操作实现
首先导入对象
Paginator
from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
在浏览器中通过GET发送当前的页码,后面加上
?page=1
如
http://127.0.0.1:8000/index.html?page=1
python后台代码
def index(request): """ Djangon内置的分页,实现的功能是上下页 :param request: :return: """ # 通过GET方式获取当前页码 current_page = request.GET.get('page') user_list = models.UserInfo.objects.all() # 获取全部的用户数据 # user_list = models.UserInfo.objects.all().count() # 获取具体的数据量 # print(user_list) # user_list = models.UserInfo.objects.all()[0:10] # 通过切片的方式获取数据 paginator = Paginator(user_list, 10) # (第一参数object_list,第二个参数per_age) # 下面是paginator的方法 # per_page: 每页显示条目数量 # count: 数据总个数 # num_pages:总页数 # page_range:总页数的索引范围,如: (1,10),(1,200) # page: 返回值是一个对象 posts = paginator.page(current_page) # 传入的是页码的值 # 下面是posts的方法 # has_next 是否有下一页 # next_page_number 下一页页码 # has_previous 是否有上一页 # previous_page_number 上一页页码 # object_list 分页之后的数据列表 # number 当前页 # paginator paginator对象 return render(request, 'index.html', {'posts': posts})
前端代码,通过posts拿到分页后的数据,上下页之前先判断是否有上一页或者下一页,之后拼接路径。
<h1>django内置的分页</h1> <ul> {% for row in posts.object_list %} {# object_list是分页之后的数据列表 #} <li>{{ row.name }}</li> {% endfor %} </ul> <div> {% if posts.has_previous %} <a href="/index.html?page={{ posts.previous_page_number }}">上一页</a> {% endif %} {% if posts.has_next %} {# 判断有下一页的时候 #} <a href="/index.html?page={{ posts.next_page_number }}">下一页</a> {% endif %} </div>
关于URL中的问题
在URL中只能接收的是int型的数字,如果传入的是字母,会报错
PageNotAnInteger at /index.html,在后台进行异常处理,捕捉异常之后的操作是返回到第一页。
在URL中传入的是负数的话,报错
EmptyPage at /index.html,处理同样是返回到第一页
已经在前面导入了异常处理的
from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
try: posts = paginator.page(current_page) # 传入的是页码的值 # except PageNotAnInteger as e: # posts = paginator.page(1) # except EmptyPage as e: # posts = paginator.page(1) except Exception as e: posts = paginator.page(1)
Django的页码
Django的页码在数据量很大的时候,会显示所有的分页的页码,比如有300条数据,每页显示10条数据,就会有30个页码。所以需要进行自己开发
在index的上下页中间添加,post下有paginator方法,paginator下有page_range 方法
<div> {% if posts.has_previous %} <a href="/index.html?page={{ posts.previous_page_number }}">上一页</a> {% endif %} {% for num in posts.paginator.page_range %} {# post下有paginator,paginator下有page_range #} <a href="/index.html?page={{ num }}">{{ num }}</a> {% endfor %} {% if posts.has_next %} {# 判断有下一页的时候 #} <a href="/index.html?page={{ posts.next_page_number }}">下一页</a> {% endif %} </div>
总结:
Django的分页适用于上下翻页的情况,不适合中间的页码
自定义分页
可以在任何地方使用,以后封装成一个类
最原始的实现
def custom(request): # 用户当前要访问的页码 current_page = request.GET.get('page') current_page = int(current_page) # 每页显示的个数 per_page = 10 # 1 1:10 最后一个取不到 # 2 10:20 # 3 20:30 start = (current_page - 1) * per_page end = current_page * per_page user_list = models.UserInfo.objects.all()[start:end] return render(request, 'custom.html', {"user_list": user_list})
把页码的计算封装成类
注意类中的参数传值的时候要一一对应
class PageInfo(object): def __init__(self, current_page, all_count, per_page, ): try: self.current_page = int(current_page) except Exception as e: current_page = 1 # url 不是 self.per_page = per_page a, b = divmod(all_count, per_page) # 通过divmod进行分页,有余数的再加一页 if b: a += 1 self.all_page = a # all_page 是总的页码 def start(self): return (self.current_page - 1) * self.per_page def end(self): return self.current_page * self.per_page def pager(self): # v = "<a href='/custom.html?page=1'>1</a>" # 双引号中中用单引号 # return v # 显示所有的页码 page_list = [] for i in range(1, self.all_page + 1): if i == self.current_page: # 判断是当前页的时候,加上背景色 # temp = "<a style='padding=5px display=inl' href='/custom.html?page=%s'>%s</a>" %(i,i) # 选中的加背景色 temp = "<a style='display: inline-block;padding: 5px;margin: 5px;background-color: red' href='/custom.html?page=%s'>%s</a>" % ( i, i) else: temp = "<a style='display: inline-block;padding: 5px;margin: 5px' href='/custom.html?page=%s'>%s</a>" % ( i, i) page_list.append(temp) return ''.join(page_list) # 把列表中的值取出并拼接成字符串 # 自定义分页 def custom(request): # 用户当前要访问的页码 # current_page = request.GET.get('page') # page_info = PageInfo(current_page,10) all_count = models.UserInfo.objects.all().count() page_info = PageInfo(request.GET.get('page'), all_count, 10) user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()] # 对象继承类的方法 return render(request, 'custom.html', {"user_list": user_list, 'page_info': page_info})
继续优化成页码的显示方式
这种是定义了固定的显示页面数11(当前页和前后5页),现在的问题是两端的极限值的问题
左边必须是当前页>=6
右边的问题是会查不到数据后还显示页码
class PageInfo(object): def __init__(self, current_page, all_count, per_page, show_page=11): try: self.current_page = int(current_page) except Exception as e: current_page = 1 # url 不是 self.per_page = per_page a, b = divmod(all_count, per_page) # 通过divmod进行分页,有余数的再加一页 if b: a += 1 self.all_page = a # all_page 是总的页码 self.show_page = show_page def start(self): return (self.current_page - 1) * self.per_page def end(self): return self.current_page * self.per_page def pager(self): # v = "<a href='/custom.html?page=1'>1</a>" # 双引号中中用单引号 # return v half = int((self.show_page-1)/2) begin = self.current_page - half stop =self.current_page +half +1 # 显示所有的页码 page_list = [] for i in range(begin,stop): if i == self.current_page: # 判断是当前页的时候,加上背景色 # temp = "<a style='padding=5px display=inl' href='/custom.html?page=%s'>%s</a>" %(i,i) # 选中的加背景色 temp = "<a style='display: inline-block;padding: 5px;margin: 5px;background-color: red' href='/custom.html?page=%s'>%s</a>" % ( i, i) else: temp = "<a style='display: inline-block;padding: 5px;margin: 5px' href='/custom.html?page=%s'>%s</a>" % ( i, i) page_list.append(temp) return ''.join(page_list) # 把列表中的值取出并拼接成字符串
优化右边的极限
- 开始一个Django的项目
- 创建一个简单的django项目
- 1、创建一个django项目
- 1、创建一个django项目
- 1、创建一个django项目
- 开始一个django项目
- 用django创建一个项目
- 1、创建一个django项目
- 1、创建一个django项目
- 1、创建一个django项目
- 以正确的方式开始一个 Django 1.4 项目
- django开发环境搭建和创建一个简单的django项目
- 如何正确开始一个python项目(django为例)
- 1、创建一个django项目
- django--今天开始正式做一个比较大的项目,先看一下基础架构
- Cocos2d-x 3.0 创建一个场景,并设置现场的时候,项目开始执行上主动
- Django笔记:1.创建一个项目
- django创建一个项目
- 1、创建一个django项目
- 1、创建一个django项目