> 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 AbstractUser
class 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
这里有教程
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默认图片
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,
});
});
avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png', max_length=200, blank=True, null=True, verbose_name='用户头像')
='avatar/%Y/%m'
MEDIA_URL = '/uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
创建uploads文件夹
= ='avatar/%Y/%m'
kindeditor图片上传返回数据格式说明:
# {"error": 1, "message": "出错信息"}
# {"error": 0, "url": "图片地址"}
配置url
from blog.upload im @
port upload_image
upload_image是upload.py里面的方法
uploadJson: '/admin/upload/kindeditor'dir_name = dir_name + '/%d/%d/' %
QuerySet[:1]这是只取出头一条信息,只是从数据库取出一条信息,而不是取出所有信息然后进行截取
href="base.html" target="_blank">{{category.name}}
{% endfor %}
{% for category in category_list %}
href="base.html" target="_blank">{{category.name}}
{% endfor %}
改为 href="base.html" target="_blank">{{category.name}}
这样不会执行sql语句,虽然views.py里面的index方法中定义了查询语句
category_liset = Category.objects.all()
这样做的话是不会执行sql语句的
如果在后面加上
for c in category_list:
这样就会执行sql语句
:type(category_list) 返回的是QuerySet type('sss')返回str
先写注释,再写代码思路会更加清晰
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)
class="autor">class="lm f_l">href="/">
{% for tag in article.tag.all %}{{ tag.name }}{% endfor %}
class="dtime f_l">{{ article.date_publish |date:'Y-m-d' }}
class="viewnum f_r">浏览(href="/">{{ article.click_count }})
class="pingl f_r">评论(href="/">{{ article.comment_set.all.count }})
{{ article.comment_set.all.count }}这么写的原因 是comment做为子表,是ForeignKey关联,内置有count方法,可以直接调用
{% for tag in article.tag.all %} tag是表,是一个多对多的关系
SELECT DISTINCT DATE_FORMAT(date_publish, '%Y-%m') as col_date FROM blog_article ORDER BY date_publish')
在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
objects = ArticleManager()
再views.py里面进行设置archive_list = Article.objects.distinct_date()
在base.html当中进行设置
{% for archive in archive_list %}
class="tutime font-size-18">href=''>{{ archive }}
{% endfor %}
这样设置后网页上不会出现需要显示的归档信息,原因是编码问题
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
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配置的时候,前面要加上 ^ 后米加上/$ $不会影响传入的参数
复制了index.html到archive.html当中,在views.py写下archive的函数,
在url当中进行引用,再到base.html当中进行设置
class="tutime font-size-18">href='{% url 'archive' %}?year={{ archive | slice:":4" }}&month={{ archive | slice:"5:7" }}'>{{ archive }}
article_list = Article.objects.filter(date_publish__icontains=year+'-'+month)
修改查询的操作,这样只会照到指定参数的内容
到archieve.html当中做一些修改
{{ request.GET.year }}/{{ request.GET.month }}归档文章
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
,所以可以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()
在到base.html当中进行修改
{% for article in article_comment_list %}
href="/" target="_blank">{{ article.title | slice:':15' }}
{% endfor %}
comment_count_list = Comment.objects.values('article').annotatennotate(comment_count=Count('article')).order_by('-comment_count')
return locals()可以直接返回当前作用域的变量,所以可以把里面的键值对的形式写成变量的形式,
article_comment_list = [Article.objects.get(pk=comment['article']) for comment in comment_count_list]
以数组的方式返回排完序的文章对象
id="slide-img-{{ ad.id }}" src="uploads/{{ ad.image_url }}"
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 }}