> virtualenv
env
# 之后会自动创建一个 env 文件夹
# 下面,有: Include,Lib,Scripts 三个文件夹
# 若要进入隔离环境
>
env
\Scripts\activate
(
env
) >
# 此时便进入了隔离环境
def global_setting():
return{'SITE_NAME':settings.SITE_NAME,
'SITE_DESC':settings.SITE_DESC,
}
'blog.views.global_setting',
SITE_NAME
采用继承的方式扩展用户信息,帮我们封装了一些用户分组和权限机制在里面
from django.contrib.auth.models import AbstractUserclass User(AbstractUser):在setttings里面声明AUTH_USER_MODEL = 'blog.User'
关联表又是什么东西?
两个表有联系,这个联系先理解为外键,这两个表就可以叫做关联表,可以是多对一,多对多,一对一
1. 新的命令
Django 1.7 为我们带来了三个新命令:
migrate: 用于执行迁移动作
makemigrations: 基于当前的model创建新的迁移策略文件
sqlmigrate: 显示迁移的SQL语句
值得注意的是, migration是基于App的, 因此, 我们可以针对某些app不启用migration功能.
2. 如何使用
migrations的使用非常简单: 修改model, 比如增加field, 然后运行
python manager.py makemigrations
你的mmodel会被扫描, 然后与之前的版本作比较, 在app的migrations目录下生成本次迁移文件.
我们建议查看一下该迁移文件, 确保没有问题. 然后运行:
python manager.py migrate
migrate命令会进行比较, 并应用该迁移.
Django标准库
Django的标准库存放在 django.contrib 包中。每个子包都是一个独立的附加功能包。 这些子包一般是互相独立的,不过有些django.contrib子包需要依赖其他子包。
在 django.contrib 中对函数的类型并没有强制要求 。其中一些包中带有模型(因此需要你在数据库中安装对应的数据表),但其它一些由独立的中间件及模板标签组成。
django.contrib 开发包共有的特性是: 就算你将整个django.contrib开发包删除,你依然可以使用 Django 的基础功能而不会遇到任何问题。 当 Django 开发者向框架增加新功能的时,他们会严格根据这一原则来决定是否把新功能放入django.contrib中。
pycharm虚拟环境virtualnv安装MySQL扩展http://my.oschina.net/NoSay/blog/474567
这里有教程
easy_install MySQL-python这个可以用,大声说一声NB
关于Django Models的设计和使用,关于在Django中配置mysql数据库,以及如何生成数据库。
# -*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
# 用户模型.
class User(AbstractUser):
avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png', max_length=200, blank=True, null=True, verbose_name='用户头像')
qq = models.CharField(max_length=20, blank=True, null=True, verbose_name='QQ号码')
mobile = models.CharField(max_length=11, blank=True, null=True, unique=True, verbose_name='手机号码')
class Meta:
verbose_name = '用户'
verbose_name_plural = verbose_name
ordering = ['-id']
def __unicode__(self):
return self.username
还需要在settings里面进行设置,#自定义用户model
AUTH_USER_MODEL = 'blog.User'
avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png', max_length=200, blank=True, null=True, verbose_name='用户头像')
ImageField是图像字段 upload_to是上传路径 default默认图片
需要在settings里面设置上传路径
配置admin
装Django1.9时,创建的superuser账号和密码不能相同,卧槽,1.9版本的密码要求很规范
from models import * admin.site.register(User) 在admin当中进行设置
models如果不加修改,以默认选择设置admin,还可以自定义models
在admin里面进行自定义
class ArticleAdmin(admin.ModelAdmin):
fields = ('title','desc','content')
admin.site.register(Article,ArticleAdmin)
如果不加后面的ArticleAdmin,就默认的形式进行设定
fields 显示指定字段 exclude 出了指定字段,显示其他字段
fieldsets可以对要设定的字段做一个很好的划分,把一部分隐藏,一部分显示
list_display可以显示指定的列
list_display_links指定列可以点击
还有很多属性,需要用的时候查阅官方文档
富文本编辑器
可以不仅仅插入文字,还可以插入图片,视频等
django-admin中添加富文本编辑器的几种方式:
1、使用第三方的一些库,如django-ckeditor
(https://pypi.python.org/pypi/django-ckeditor)
2、在admin中定义富文本编辑器的widget
3、通过定义ModelAdmin的媒体文件
步骤:
1、下载kindeditor
复制到static的js目录下
2、定义ModelAdmin的媒体文件
这个是在admin当中进行配置的
class ArticleAdmin(admin.ModelAdmin):
exclude = ('title','desc','content')
class Media:
js = (
'/static/js/kindeditor-4.1.10/kindeditor-min.js',
'/static/js/kindeditor-4.1.10/lang/zh_CN.js',
'/static/js/kindeditor-4.1.10/config.js',
)3、修改kindeditor的配置文件
也就是在config.js文件中新建一个对象
asp asp.net examples jsp php 这些文件可以删除
在KinderEditor的官方文档照到相应的配置
然后再config.js当中进行配置
KindEditor.ready(function(K) {
K.create('textarea[name=content]',{
width:800,
height:200,
});
});
Pillow是python的一个图像处理库,django-ckeditor需要依赖该库。最简单的安装方法,当然是使用pip,假设你装过pip,可以直接运行以下命令安装:
上传文件
KinderEditor没有提供python的上传文件的接口,所以需要自己进行配置
固定上传的目录为uploads
url(r"^uploads/(?P<path>.*)$", \
"django.views.static.serve", \
{"document_root": settings.MEDIA_ROOT,}),
uploads 是说明这是一个路由的地址,(?P<path>.*)$"这里可以是任意字符, "django.views.static.serve"是调用django里面的server方法
"
document_root": settings.MEDIA_ROOT,这是对应路径
avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png', max_length=200, blank=True, null=True, verbose_name='用户头像')
upload_to='avatar/%Y/%m'自定义上传路径,上传到指定文件
步骤:
在settings.py文件里面进行设置
MEDIA_URL = '/uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
创建uploads文件夹
在url文件当中引入settings from django.conf import settings
url(r"^uploads/(?P<path>.*)$", \ "django.views.static.serve", \ {"document_root": settings.MEDIA_ROOT,}),
avatar = models.ImageField(upload_to='avatar/%Y/%m',在models里面已经设置了上传路径,是在settings里面设置的路径下面,这里写的是avatar/年/月 存储
http://localhost:8000/uploads/avatar/2015/12/mamao.jpg 因为在url里面有设置,所以可以直接在输入url也可以访问到
富文本编辑器上传文件:
在blog下面新建一个models.py文件,直接找写好的代码
kindeditor图片上传返回数据格式说明:
# {"error": 1, "message": "出错信息"}
# {"error": 0, "url": "图片地址"}
配置url
from blog.upload im @csrf_exempt 这个装饰器的作用是 不再做远程表单提交验证
port upload_image
url(r'^admin/upload/(?P<dir_name>[^/]+)$', upload_image, name='upload_image'),
upload_image是upload.py里面的方法
dir_name 是和upload_image里面的传入参数相对应的
在KendEditor设置上传路径,也就是先前设置富文本编辑器创建的config.js文件
uploadJson: '/admin/upload/kindeditor', 这个路径是先前在url已经定义好的,这里定义了在uplaod文件夹下面的kindeditor文件夹dir_name = dir_name + '/%d/%d/' %(today.year,today.month)在uploads.py里面已经进行了定义了在kindeditor目录下的路径
基本查询
导入models在views.py里面,
在index里面进行设置,category_list = Category.objects.all()[:1]导入分类信息,
return render(request,'index.html',{'category_list':category_list})将信息传入到category_list当中
QuerySet[:1]这是只取出头一条信息,只是从数据库取出一条信息,而不是取出所有信息然后进行截取
直接在base.html当中进行引用
{% for category in category_list %}
<a href="base.html" target="_blank">{{category.name}}</a>
{% endfor %}
怎么理解QuerySet的查询是惰性的(当我们去执行all,filter,get,是不会去执行sql的,
当我们去调用查询结果集的时候会执行sql)
{% for category in category_list %}
<a href="base.html" target="_blank">{{category.name}}</a>
{% endfor %}
改为 <a href="base.html" target="_blank">{{category.name}}</a>
这样不会执行sql语句,虽然views.py里面的index方法中定义了查询语句
category_liset = Category.objects.all()
这样做的话是不会执行sql语句的
如果在后面加上
for c in category_list:
print(c)
这样就会执行sql语句
小技巧:type(category_list) 返回的是QuerySet type('sss')返回str
先写注释,再写代码思路会更加清晰
以models当中的数据表为对象,在html里面进行操作,在views里面进行逻辑操作,传递参数给html,
在views里面先导入相关的模块
from django.core.paginator import Paginator,InvalidPage,EmptyPage,PageNotAnInteger
article_list = Article.objects.all()
paginator = Paginator(article_list,2)
try:
page = int(request.GET.get('page',1))
article_list = paginator.page(page)
except (EmptyPage,InvalidPage,PageNotAnInteger):
article_list = paginator.page(1)
<p class="autor"><span class="lm f_l"><a href="/">
{% for tag in article.tag.all %}{{ tag.name }}</a></span>{% endfor %}
<span class="dtime f_l">{{ article.date_publish |date:'Y-m-d' }}</span>
<span class="viewnum f_r">浏览(<a href="/">{{ article.click_count }}</a>)
</span><span class="pingl f_r">评论(<a href="/">{{ article.comment_set.all.count }}</a>)
</span></p>
{{ article.comment_set.all.count }}这么写的原因 是comment做为子表,是ForeignKey关联,内置有count方法,可以直接调用
{% for tag in article.tag.all %} tag是表,是一个多对多的关系
去重复方法:distinct是Django自带的去重复方法,对整个字段进行去重
3、django中直接使用sql的两种方式
SELECT DISTINCT DATE_FORMAT(date_publish, '%Y-%m') as col_date FROM blog_article ORDER BY date_publish
3.1、raw (异常:Raw query must include the primary key,返回结果必须包含主键)
3.2、excute
可以直接在Django中写sql语句进行查询,但不推荐这种方式
如 Article.objects.raw('SELECT DISTINCT DATE_FORMAT(date_publish, '%Y-%m') as col_date FROM blog_article ORDER BY date_publish')
这样可以直接进行查询
自定义文章model的管理器,因为想要实现按年月吧文章归档的操作实现不了,所以自定义一个model来实现这个功能
有两种方式
1:新加一个数据处理的方法
2.改变原有的queryset,就是重新定义这个方法,改变这个方法的返回
主要使用第一种方法
在models.py里面自定义Model管理器
class ArticleManager(models.Manager):
distinct_date_list = []
def distinct_date(self):
date_list = self.values('date_publish')
#把日期的结果取出来
for date in date_list:
date = date['date_publish'].strftime('%Y%m文章存档')
if date not in distinct_date_list:
distinct_date_list.append(date)
return distinct_date_list
在Article的类中进行设置
objects = ArticleManager()
再views.py里面进行设置archive_list = Article.objects.distinct_date()
在base.html当中进行设置
<ul>
{% for archive in archive_list %}
<li>
<p><span class="tutime font-size-18"><a href=''>{{ archive }}</a></span></p>
</li>
{% endfor %}
</ul>
这样设置后网页上不会出现需要显示的归档信息,原因是编码问题
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
导入这个在models.py里面就可以了
http://blog.csdn.net/crazyhacking/article/details/39375535
http://blog.csdn.net/intel80586/article/details/8566057
python在解码的时候默认 以ASCLL码的方式进行解码
靠,今天实在是太粗心了,好恶心,就这么几分钟就能搞定的事情,花了我近一个小时,日
url(r'^archive/$',archive,name='archive')
url配置的时候,前面要加上 ^ 后米加上/$ $不会影响传入的参数
配置archive.html
复制了index.html到archive.html当中,在views.py写下archive的函数,
在url当中进行引用,再到base.html当中进行设置
<p><span class="tutime font-size-18"><a href='{% url 'archive' %}?year={{ archive | slice:":4" }}&month={{ archive | slice:"5:7" }}'>{{ archive }}</a></span></p>
使点击分类文章时会跳转到archive.html当中,
再到views.html当中进行设置其逻辑结构
将index函数里面的分页查询的代码拷贝下来,就可以显示内容了
article_list = Article.objects.filter(date_publish__icontains=year+'-'+month)
修改查询的操作,这样只会照到指定参数的内容
到archieve.html当中做一些修改
<h2>{{ request.GET.year }}/{{ request.GET.month }}归档文章</h2>
发现在这里也可以使用传进来的参数
这里需要传入参数,因为QuerySet查询是惰性的,不会一下子查询出所有的记录只会查询出当前页面的内容,所以当跳转页面的时候,应该重新传入参数
重构代码:将重复的代码提取出来
卧槽,今天有点不顺啊,url(r'$',index,name='index'),这个前面不加^这个,然而刚刚我加上了,就报了一个404错误
把index和archive里面相同的代码提取出来放到global_settings里面
def global_setting(request):
#分类信息获取(导航数据)
category_list = Category.objects.all()
#文章归档数据
archive_list = Article.objects.distinct_date()
return {
'category_list':category_list,
'archive_list':archive_list,
'SITE_NAME':settings.SITE_NAME,
'SITE_DESC':settings.SITE_DESC,
}
还有一些数据也可以放到global_settings里面
如:广告数据,标签云数据,友情链接数据,文章排行榜数据
优化url:
当app多了的时候维护url变得困难,所以就选择在每个app下面建立url进行优化这种操作
复制工程下面的url到app当中,在工程当中:删除工程url当中app相关url改为include在本项目中
所做的修改是:url('^',include(blog.urls)) 还要导入includefrom django.conf.urls import url,include
app url 删除相关引入import只保留和app相关的url和import,
在views.py里面封装分页代码:
因为函数index和函数archive都有分页代码,所以可以把分页代码分装成一个函数来引用
def getPage(request,article_list):
paginator = Paginator(article_list,2)
try:
page = int(request.GET.get('page',1))
article_list = paginator.page(page)
except (EmptyPage,InvalidPage,PageNotAnInteger):
article_list = paginator.page(1)
return article_list
因为始终是对取出来的内容进行的修改所以就直接返回article_list,在article_list当中,还需要用到request,
所以这里需要传入request
archive.html和index.html都有上一页,下一页,所以可以Include提取出来
新建一个pagination.html把分页的代码直接复制进去,在到相应的位置,以{% include 'pagination.html' %}代替
然后发现archive的页面在按下一页后,参数没有传递过去,所以需要一个判断拼接字符串
文章排行:order_by()需要指定字段,不能这样使用Article.objects.all().order_by()
选择将文章进行分组,然后使用count函数
我发现凡是涉及到显示数据内容,都会牵扯到数据库操作,不一定,可以是settings里面设置的全局变量
return {
'category_list':category_list,
'archive_list':archive_list,
'SITE_NAME':settings.SITE_NAME,
'SITE_DESC':settings.SITE_DESC,
}
#站点基本信息设置
SITE_NAME = settings.SITE_NAME
SITE_DESC = settings.SITE_DESC
comment_count_list = Comment.objects.values('article').annotate(comment_count=Count('article')).order_by('-comment_count')
article_comment_list = [Article.objects.get(pk=comment['article']) for comment in comment_count_list]
return locals()
经验证,comment['article']为Article当中的id编号
在到base.html当中进行修改
<ul>
{% for article in article_comment_list %}
<li><a href="/" target="_blank">{{ article.title | slice:':15' }}</a></li>
{% endfor %}
</ul>
comment_count_list = Comment.objects.values('article').annotatennotate(comment_count=Count('article')).order_by('-comment_count')
.annotate的使用方法,Count的使用方法,return locals()可以直接返回当前作用域的变量,所以可以把里面的键值对的形式写成变量的形式,
article_comment_list = [Article.objects.get(pk=comment['article']) for comment in comment_count_list]
以数组的方式返回排完序的文章对象
自定义过滤器:
DoseNotExist异常,如果使用get没有获得对象,那么返回一个DoseNotExist异常
safe过滤器,把html转换成页面信息,不会直接打印出来
在templatetags包里面定义一个html使用的时候需要加载到html当中
在此html当中
from django import template
register = remplate.Library()
@register.filter
def month_to_upper(key):
return[] [key.month-1]
register.filter('month_to_upper',month_to_upper)
浏览排行:
浏览量可以直接从Article的click_count中取出,所以可以直接通过取出Article所有对象然后对click_count进行排序即可
评论排行:
评论排行和浏览排行不同,Comment和Article是关联表,需要进行间接的排序,这里需要讨论一下
标签云:
标签有一个Tag的类,子表是Article,所以可以在把tag_list取出放到global当中,然后在views.py当中定义tag函数,当点击tag的时候可以进行跳转,所以还要一个tag.html,在tag函数中主要是取出Article的对象,其它不变,筛选条件是,先取出Tag对象,取出Tag的点击对象,当点击的时候,应该把点击标签的id传过去,再取出对应的Article
友情链接:
友情链接的数据都已经写好了,所以可以直接在global当中取出Links的对象
广告:
<img id="slide-img-{{ ad.id }}" src="uploads/{{ ad.image_url }}"
图片的src目前有三种情况
1:绝对路径
2:静态文件的相对路径<img id="slide-img-1" src="{% static 'images/a1.jpg' %}" alt="" />
3:上传文件的路径<img id="slide-img-{{ ad.id }}" src="uploads/{{ ad.image_url }}" 直接写uploads文件夹加上传文件地址相当于就是绝对路径
src="../uploads/{{ ad.image_url }}"这里面需要加引号,写的就是绝对路径
引用关联外键里面的内容:
class Article(models.Model):
date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
user = models.ForeignKey(User, verbose_name='用户')
article = Article.objects.get(pk=id)
{{ article.user.username }}
avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png', max_length=200, blank=True, null=True, verbose_name='用户头像')
ImageField是图像字段 upload_to是上传路径 default默认图片
需要在settings里面设置上传路径
class ArticleAdmin(admin.ModelAdmin):
fields = ('title','desc','content')
admin.site.register(Article,ArticleAdmin)如果不加后面的ArticleAdmin,就默认的形式进行设定fields 显示指定字段 exclude 出了指定字段,显示其他字段
class ArticleAdmin(admin.ModelAdmin):
exclude = ('title','desc','content')
class Media:
js = (
'/static/js/kindeditor-4.1.10/kindeditor-min.js',
'/static/js/kindeditor-4.1.10/lang/zh_CN.js',
'/static/js/kindeditor-4.1.10/config.js',
KindEditor.ready(function(K) {
K.create('textarea[name=content]',{
width:800,
height:200,
});
});
Pillow是python的一个图像处理库,django-ckeditor需要依赖该库。最简单的安装方法,当然是使用pip,假设你装过pip,可以直接运行以下命令安装:
上传文件KinderEditor没有提供python的上传文件的接口,所以需要自己进行配置固定上传的目录为uploadsurl(r"^uploads/(?P<path>.*)$", \
"django.views.static.serve", \
{"document_root": settings.MEDIA_ROOT,}),
uploads 是说明这是一个路由的地址,(?P<path>.*)$"这里可以是任意字符, "django.views.static.serve"是调用django里面的server方法
"document_root": settings.MEDIA_ROOT,这是对应路径
avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png', max_length=200, blank=True, null=True, verbose_name='用户头像')upload_to='avatar/%Y/%m'自定义上传路径,上传到指定文件步骤:在settings.py文件里面进行设置MEDIA_URL = '/uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')创建uploads文件夹在url文件当中引入settings from django.conf import settingsurl(r"^uploads/(?P<path>.*)$", \ "django.views.static.serve", \ {"document_root": settings.MEDIA_ROOT,}),
avatar = models.ImageField(upload_to='avatar/%Y/%m',在models里面已经设置了上传路径,是在settings里面设置的路径下面,这里写的是avatar/年/月 存储http://localhost:8000/uploads/avatar/2015/12/mamao.jpg 因为在url里面有设置,所以可以直接在输入url也可以访问到富文本编辑器上传文件:在blog下面新建一个models.py文件,直接找写好的代码kindeditor图片上传返回数据格式说明:# {"error": 1, "message": "出错信息"}
# {"error": 0, "url": "图片地址"}配置urlfrom blog.upload im @csrf_exempt 这个装饰器的作用是 不再做远程表单提交验证port upload_imageurl(r'^admin/upload/(?P<dir_name>[^/]+)$', upload_image, name='upload_image'),upload_image是upload.py里面的方法dir_name 是和upload_image里面的传入参数相对应的在KendEditor设置上传路径,也就是先前设置富文本编辑器创建的config.js文件uploadJson: '/admin/upload/kindeditor', 这个路径是先前在url已经定义好的,这里定义了在uplaod文件夹下面的kindeditor文件夹dir_name = dir_name + '/%d/%d/' %(today.year,today.month)在uploads.py里面已经进行了定义了在kindeditor目录下的路径
QuerySet[:1]这是只取出头一条信息,只是从数据库取出一条信息,而不是取出所有信息然后进行截取
<a href="base.html" target="_blank">{{category.name}}</a>
{% endfor %}
{% for category in category_list %}
<a href="base.html" target="_blank">{{category.name}}</a>
{% endfor %}
改为 <a href="base.html" target="_blank">{{category.name}}</a>
这样不会执行sql语句,虽然views.py里面的index方法中定义了查询语句
category_liset = Category.objects.all()
这样做的话是不会执行sql语句的
如果在后面加上
for c in category_list:
print(c)
这样就会执行sql语句
小技巧:type(category_list) 返回的是QuerySet type('sss')返回str
先写注释,再写代码思路会更加清晰
以models当中的数据表为对象,在html里面进行操作,在views里面进行逻辑操作,传递参数给html,
在views里面先导入相关的模块
from django.core.paginator import Paginator,InvalidPage,EmptyPage,PageNotAnInteger
article_list = Article.objects.all()
paginator = Paginator(article_list,2)
try:
page = int(request.GET.get('page',1))
article_list = paginator.page(page)
except (EmptyPage,InvalidPage,PageNotAnInteger):
article_list = paginator.page(1)
<p class="autor"><span class="lm f_l"><a href="/">{% for tag in article.tag.all %}{{ tag.name }}</a></span>{% endfor %}<span class="dtime f_l">{{ article.date_publish |date:'Y-m-d' }}</span><span class="viewnum f_r">浏览(<a href="/">{{ article.click_count }}</a>)</span><span class="pingl f_r">评论(<a href="/">{{ article.comment_set.all.count }}</a>)</span></p>
{{ article.comment_set.all.count }}这么写的原因 是comment做为子表,是ForeignKey关联,内置有count方法,可以直接调用{% for tag in article.tag.all %} tag是表,是一个多对多的关系
去重复方法:distinct是Django自带的去重复方法,对整个字段进行去重
3、django中直接使用sql的两种方式
SELECT DISTINCT DATE_FORMAT(date_publish, '%Y-%m') as col_date FROM blog_article ORDER BY date_publish
3.1、raw (异常:Raw query must include the primary key,返回结果必须包含主键)
3.2、excute
可以直接在Django中写sql语句进行查询,但不推荐这种方式
如 Article.objects.raw('SELECT DISTINCT DATE_FORMAT(date_publish, '%Y-%m') as col_date FROM blog_article ORDER BY date_publish')
这样可以直接进行查询
自定义文章model的管理器,因为想要实现按年月吧文章归档的操作实现不了,所以自定义一个model来实现这个功能
有两种方式
1:新加一个数据处理的方法
2.改变原有的queryset,就是重新定义这个方法,改变这个方法的返回
主要使用第一种方法
在models.py里面自定义Model管理器
class ArticleManager(models.Manager):distinct_date_list = []
def distinct_date(self):date_list = self.values('date_publish')
#把日期的结果取出来
for date in date_list:
date = date['date_publish'].strftime('%Y%m文章存档')
if date not in distinct_date_list:
distinct_date_list.append(date)
return distinct_date_list
在Article的类中进行设置
objects = ArticleManager()再views.py里面进行设置archive_list = Article.objects.distinct_date()在base.html当中进行设置
<ul>
{% for archive in archive_list %}
<li>
<p><span class="tutime font-size-18"><a href=''>{{ archive }}</a></span></p>
</li>
{% endfor %}
</ul>这样设置后网页上不会出现需要显示的归档信息,原因是编码问题
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
导入这个在models.py里面就可以了
http://blog.csdn.net/crazyhacking/article/details/39375535
http://blog.csdn.net/intel80586/article/details/8566057
python在解码的时候默认 以ASCLL码的方式进行解码
靠,今天实在是太粗心了,好恶心,就这么几分钟就能搞定的事情,花了我近一个小时,日
url(r'^archive/$',archive,name='archive')
url配置的时候,前面要加上 ^ 后米加上/$ $不会影响传入的参数
配置archive.html
复制了index.html到archive.html当中,在views.py写下archive的函数,
在url当中进行引用,再到base.html当中进行设置
<p><span class="tutime font-size-18"><a href='{% url 'archive' %}?year={{ archive | slice:":4" }}&month={{ archive | slice:"5:7" }}'>{{ archive }}</a></span></p>
使点击分类文章时会跳转到archive.html当中,
再到views.html当中进行设置其逻辑结构
article_list = Article.objects.filter(date_publish__icontains=year+'-'+month)
修改查询的操作,这样只会照到指定参数的内容
到archieve.html当中做一些修改
<h2>{{ request.GET.year }}/{{ request.GET.month }}归档文章</h2>
def global_setting(request):
#分类信息获取(导航数据)
category_list = Category.objects.all()
#文章归档数据
archive_list = Article.objects.distinct_date()
return {
'category_list':category_list,
'archive_list':archive_list,
'SITE_NAME':settings.SITE_NAME,
'SITE_DESC':settings.SITE_DESC,
}
def getPage(request,article_list):
paginator = Paginator(article_list,2)
try:
page = int(request.GET.get('page',1))
article_list = paginator.page(page)
except (EmptyPage,InvalidPage,PageNotAnInteger):
article_list = paginator.page(1)
return article_list
因为始终是对取出来的内容进行的修改所以就直接返回article_list,在article_list当中,还需要用到request,
所以这里需要传入request
archive.html和index.html都有上一页,下一页,所以可以Include提取出来
新建一个pagination.html把分页的代码直接复制进去,在到相应的位置,以{% include 'pagination.html' %}代替
然后发现archive的页面在按下一页后,参数没有传递过去,所以需要一个判断拼接字符串
return {
'category_list':category_list,
'archive_list':archive_list,
'SITE_NAME':settings.SITE_NAME,
'SITE_DESC':settings.SITE_DESC,
}
#站点基本信息设置
SITE_NAME = settings.SITE_NAME
SITE_DESC = settings.SITE_DESC
comment_count_list = Comment.objects.values('article').annotate(comment_count=Count('article')).order_by('-comment_count')
article_comment_list = [Article.objects.get(pk=comment['article']) for comment in comment_count_list]
return locals()经验证,comment['article']为Article当中的id编号在到base.html当中进行修改<ul>
{% for article in article_comment_list %}
<li><a href="/" target="_blank">{{ article.title | slice:':15' }}</a></li>
{% endfor %}
</ul>
comment_count_list = Comment.objects.values('article').annotatennotate(comment_count=Count('article')).order_by('-comment_count')
.annotate的使用方法,Count的使用方法,return locals()可以直接返回当前作用域的变量,所以可以把里面的键值对的形式写成变量的形式,
article_comment_list = [Article.objects.get(pk=comment['article']) for comment in comment_count_list]以数组的方式返回排完序的文章对象
<img id="slide-img-{{ ad.id }}" src="uploads/{{ ad.image_url }}"
图片的src目前有三种情况
1:绝对路径
2:静态文件的相对路径<img id="slide-img-1" src="{% static 'images/a1.jpg' %}" alt="" />
3:上传文件的路径<img id="slide-img-{{ ad.id }}" src="uploads/{{ ad.image_url }}" 直接写uploads文件夹加上传文件地址相当于就是绝对路径
src="../uploads/{{ ad.image_url }}"这里面需要加引号,写的就是绝对路径
class Article(models.Model):
date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
user = models.ForeignKey(User, verbose_name='用户')
article = Article.objects.get(pk=id)
{{ article.user.username }}