1. 引言
2. 分析
- 数据从mongodb中获取
- 每页显示多少条数据
- 翻页功能有
前一页
,显示当前页和总页数
,后一页
3. 实现
3.1 在settings.py中增加mongo的连接
from mongoengine import connect
connect('58toncheng', host='127.0.0.1', port=27017)
settings.py全部内容如下
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '921jusx@-^@!qolo+aul2(_#*6k!_)+z&)9ci)+nf@i35_=r52'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'pure',
]
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',
]
ROOT_URLCONF = 'django_web.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'django_web.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
# 连接mongodb, 在其它模块文件中就能引用了
from mongoengine import connect
# connect('blog', host='127.0.0.1', port=27017)
connect('58tongcheng', host='127.0.0.1', port=27017)
3.2 在models.py中定义类模型获取数据
models.py全部内容如下
from django.db import models
from mongoengine import *
# # 这里导入只是为了此文件方便测试, 实际运行中在settings中导入
# from mongoengine import connect
# # connect('58tongcheng', host='127.0.0.1', port=27017)
# connect('blog', host='127.0.0.1', port=27017)
# Create your models here.
class ArtiInfo(Document):
# 变量名要和库中的一致, 且库中的所有字段都要写进来
# des = StringField()
# title = StringField().png' %}
# scores = StringField()
# tags = ListField(StringField())
# 表示字符串
pub_date = StringField()
look = StringField()
# 表示字符串列表
area = ListField(StringField())
title = StringField()
cates = ListField(StringField())
# 表示整型
price = IntField()
time = IntField()
url = StringField()
# 因为是取数据所以必须要告诉从哪个collection中取得数据, 如果是新建就没有必要了
# meta = {'collection': 'arti_info'}
meta = {'collection': 'item_info'}
# 输出看下i相当于Document字典, 所以取出字典中的值, []中的数字表示要取出几条数据
# for i in ArtiInfo.objects[:2]:
# print(i.des, i.title, i.scores, i.tags)
# print(i.pub_date, i.look, i.area, i.price, i.time)
3.3 在views.py中定义视图函数home
, index
views.py全部内容如下
from django.shortcuts import render
# 从模块中导入类ArtiInfo
from pure.models import ArtiInfo
from django.core.paginator import Paginator
# Create your views here.
# 定义视力函数返回原始页面
def home(request):
return render(request, 'index.html')
# 定义视力函数返回包含上下文且有翻页功能的页面
def index(request):
# 可以直接在这里定义上下文
'''
context = {
'title': 'Just a title',
'des': 'Just a description',
'score': '1.0'
}
'''
# des = StringField()
# title = StringField()
# scores = StringField()
# tags = ListField(StringField())
# 多少条为一页, 这里是4条为一页
limit = 4
# 类实例化, 即变量arti_info被赋予了类Arties = StringField()
arti_info = ArtiInfo.objects
# 对数据进行分页
paginator = Paginator(arti_info, limit)
# 获取当前分页的页码数
page = request.GET.get('page', 1)
# 查看下request是什么内容
print(request) # <WSGIRequest: GET '/index/?page=17'>
# 查看下request.GET又是什么内容
print(request.GET) # <QueryDict: {'page': ['17']}>
# 装载指定的页
loaded = paginator.page(page)
'''
context = {
'title': arti_info[0].title,
'des': arti_info[0].des,
'score': arti_info[0].scores,
}
'''
# context中的ArtiInfo可以随便是其它的名字
context = {'ArtiInfo': loaded}
# 返回数据包括上下文context
return render(request, 'index_paginator_58.html', context)
# Paginator用法说明
'''
iter = 'aaaabbbbccccddddeeee'
paginator = Paginator(iter, 4)
page1 = paginator.page(1) 分页1
page1.object_list 当前分页内容
out: 'aaaa'
page3 = paginator.page(3) 分页3
page3.object_list 当前页内容
out: 'cccc'
page3.has_next() 当前分页是否有下一页
out: True
page3.number 当前分页的页码: 3
page3.paginator.num_pages 总共有几个分页
out: 5
page5 = paginator.page(5)
page5.has_next() 最后一页没有分页了
out: False
'''
3.4 在urls.py中添加index
, home
url
urls.py全部内容如下
from django.conf.urls import url
from django.contrib import admin
from pure.views import home, index
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^home/', home),
url(r'^index/', index),
]
3.5 最后修改模板文件
index.html全部内容如下
{% load static %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A layout example that shows off a blog page with a list of posts.">
<title>Blog – Layout Examples – Pure</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
<!--[if lte IE 8]>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/grids-responsive-old-ie-min.css">
<![endif]-->
<!--[if gt IE 8]><!-->
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/grids-responsive-min.css">
<!--<![endif]-->
<!--[if lte IE 8]>
<link rel="stylesheet" href="css/layouts/blog-old-ie.css">
<![endif]-->
<!--[if gt IE 8]><!-->
<link rel="stylesheet" href="{% static 'css/layouts/blog.css'%}">
<!--<![endif]-->
</head>
<body>
<div id="layout" class="pure-g">
<div class="sidebar pure-u-1 pure-u-md-1-4">
<div class="header">
<h1 class="brand-title">A Sample Blog</h1>
<h2 class="brand-tagline">Creating a blog layout using Pure</h2>
<nav class="nav">
<ul class="nav-list">
<li class="nav-item">
<a class="pure-button" href="http://purecss.io">Pure</a>
</li>
<li class="nav-item">
<a class="pure-button" href="http://yuilibrary.com">YUI Library</a>
</li>
</ul>
</nav>
</div>
</div>
<div class="content pure-u-1 pure-u-md-3-4">
<div>
<!-- A wrapper for all the blog posts -->
<div class="posts">
<h1 class="content-subhead">Pinned Post</h1>
<!-- A single blog post -->
<section class="post">
<header class="post-header">
<img class="post-avatar" alt="Tilo Mitra's avatar" height="48" width="48" src="{% static 'img/common/tilo-avatar.png' %}">
<h2 class="post-title">Introducing Pure</h2>
<p class="post-meta">
By <a href="#" class="post-author">Tilo Mitra</a> under <a class="post-category post-category-design" href="#">CSS</a> <a class="post-category post-category-pure" href="#">Pure</a>
</p>
</header>
<div class="post-description">
<p>
Yesterday at CSSConf, we launched Pure – a new CSS library. Phew! Here are the <a href="https://speakerdeck.com/tilomitra/pure-bliss">slides from the presentation</a>. Although it looks pretty minimalist, we’ve been working on Pure for several months. After many iterations, we have released Pure as a set of small, responsive, CSS modules that you can use in every web project.
</p>
</div>
</section>
</div>
<div class="posts">
<h1 class="content-subhead">Recent Posts</h1>
<section class="post">
<header class="post-header">
<img class="post-avatar" alt="Eric Ferraiuolo's avatar" height="48" width="48" src="{% static 'img/common/ericf-avatar.png' %}">
<h2 class="post-title">Everything You Need to Know About Grunt</h2>
<p class="post-meta">
By <a class="post-author" href="#">Eric Ferraiuolo</a> under <a class="post-category post-category-js" href="#">JavaScript</a>
</p>
</header>
<div class="post-description">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</p>
</div>
</section>
<section class="post">
<header class="post-header">
<img class="post-avatar" alt="Reid Burke's avatar" height="48" width="48" src="{% static 'img/common/reid-avatar.png' %}">
<h2 class="post-title">Photos from CSSConf and JSConf</h2>
<p class="post-meta">
By <a class="post-author" href="#">Reid Burke</a> under <a class="post-category" href="#">Uncategorized</a>
</p>
</header>
<div class="post-description">
<div class="post-images pure-g">
<div class="pure-u-1 pure-u-md-1-2">
<a href="http://www.flickr.com/photos/uberlife/8915936174/">
<img alt="Photo of someone working poolside at a resort"
class="pure-img-responsive"
src="http://farm8.staticflickr.com/7448/8915936174_8d54ec76c6.jpg">
</a>
<div class="post-image-meta">
<h3>CSSConf Photos</h3>
</div>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<a href="http://www.flickr.com/photos/uberlife/8907351301/">
<img alt="Photo of the sunset on the beach"
class="pure-img-responsive"
src="http://farm8.staticflickr.com/7382/8907351301_bd7460cffb.jpg">
</a>
<div class="post-image-meta">
<h3>JSConf Photos</h3>
</div>
</div>
</div>
</div>
</section>
<section class="post">
<header class="post-header">
<img class="post-avatar" alt="Andrew Wooldridge's avatar" height="48" width="48" src="{% static 'img/common/andrew-avatar.png' %}">
<h2 class="post-title">YUI 3.10.2 Released</h2>
<p class="post-meta">
By <a class="post-author" href="#">Andrew Wooldridge</a> under <a class="post-category post-category-yui" href="#">YUI</a>
</p>
</header>
<div class="post-description">
<p>
We are happy to announce the release of YUI 3.10.2! You can find it now on the Yahoo! CDN, download it directly, or pull it in via npm. We’ve also updated the YUI Library website with the latest documentation.
</p>
</div>
</section>
</div>
<div class="footer">
<div class="pure-menu pure-menu-horizontal">
<ul>
<li class="pure-menu-item"><a href="http://purecss.io/" class="pure-menu-link">About</a></li>
<li class="pure-menu-item"><a href="http://twitter.com/yuilibrary/" class="pure-menu-link">Twitter</a></li>
<li class="pure-menu-item"><a href="http://github.com/yahoo/pure/" class="pure-menu-link">GitHub</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
index_paginator_58.html全部内容如下
{#如果views中是直接定义的context, 则这里就可以直接写context字典中的键值了#}
{#{{ des }}#}
{#{{ title }}#}
{#{{ score }}#}
{% load static %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A layout example that shows off a blog page with a list of posts.">
<title>Blog – Layout Examples – Pure</title>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
<!--[if lte IE 8]>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/grids-responsive-old-ie-min.css">
<![endif]-->
<!--[if gt IE 8]><!-->
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/grids-responsive-min.css">
<!--<![endif]-->
<!--[if lte IE 8]>
<link rel="stylesheet" href="{% static 'css/layouts/blog-old-ie.css' %}">
<![endif]-->
<!--[if gt IE 8]><!-->
<link rel="stylesheet" href="{% static 'css/layouts/blog.css' %}">
<!--<![endif]-->
</head>
<body>
<div id="layout" class="pure-g">
<div class="sidebar pure-u-1 pure-u-md-1-4">
<div class="header">
<h1 class="brand-title">A Sample Blog</h1>
<h2 class="brand-tagline">Creating a blog layout using Pure</h2>
<nav class="nav">
<ul class="nav-list">
<li class="nav-item">
<a class="pure-button" href="http://purecss.io">Pure</a>
</li>
<li class="nav-item">
<a class="pure-button" href="http://yuilibrary.com">YUI Library</a>
</li>
</ul>
</nav>
</div>
</div>
<div class="content pure-u-1 pure-u-md-3-4">
<div>
<!-- A wrapper for all the blog posts -->
<div class="posts">
<h1 class="content-subhead">Recent Posts</h1>
<!-- 循环显示项, views视图中的limit限制多少条为一页 -->
{% for item in ArtiInfo %}
<section class="post">
<header class="post-header">
<h3 class="post-title">RMB: {{ item.price }} - {{ item.pub_date }}</h3>
<p class="post-meta">
<span class="post-category">{{ item.look }}</span>
{% for cate in item.cates %}
<a class="post-category post-category-js" href="#">{{ cate }}</a>
{% endfor %}
{% for area in item.area %}
<a class="post-category-design" href="#">{{ area }}</a>
{% endfor %}
</p>
</header>
<div class="post-description">
<p>
{{ item.title }}
</p>
</div>
</section>
{% endfor %}
</div>
<div>
{% if ArtiInfo.has_previous %}
<a href="?page={{ ArtiInfo.previous_page_number }}">< Pre</a>
{% endif %}
<span>{{ ArtiInfo.number }} of {{ ArtiInfo.paginator.num_pages }}</span>
{% if ArtiInfo.has_next %}
<a href="?page={{ ArtiInfo.next_page_number }}">Next ></a>
{% endif %}
</div>
<div class="footer">
<div class="pure-menu pure-menu-horizontal">
<ul>
<li class="pure-menu-item"><a href="http://purecss.io/" class="pure-menu-link">About</a></li>
<li class="pure-menu-item"><a href="http://twitter.com/yuilibrary/" class="pure-menu-link">Twitter</a></li>
<li class="pure-menu-item"><a href="http://github.com/yahoo/pure/" class="pure-menu-link">GitHub</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<div class="main-content-pagitor">
{% if ArtiInfo.has_previous %}
<a href="?page={{ ArtiInfo.previous_page_number }}">< Pre</a>
{% endif %}
<span> {{ ArtiInfo.number }} of {{ ArtiInfo.paginator.num_pages }} </span>
{% if ArtiInfo.has_next %}
<a href="?page={{ ArtiInfo.next_page_number }}">Next ></a>
{% endif %}
</div>
3.6 访问页面
运行服务: python3 manage.py runserver
http://127.0.0.1/home
4. 总结
用mongoengine连接mongodb更方便
在models.py中可定义获取数据库数据的ORM模型
mongoengine中的Document包含
StringFiled
,IntField
,ListField
等定义ORM时, 变量名要和数据库一致且要包含全部字段
-
django.core.paginator中的Paginator有按条目限制的分页:
- paginator = Paginator(iter, 4) // 表示每4条分一页
- paginator.page(1) // 分页1
- paginator.page(1).object_list // 显示当前分页内容
- paginator.page(1).has_previous() // 当前分页是否有上一页
- paginator.page(1).has_next() // 当前分页是否有下一页
- paginator.page(1).paginator.num_pages // 总共分页的数量
- paginator.page(1).previous_page_number // 上一页页码
- paginator.page(1).next_page_number // 下一页页码
-
网页中的循环及判断
- {% for xxx in oo %} blabla {% endfor %}
- {% if something %} blabla {% endif %}