> 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'
關聯表又是什麼東西?
兩個表有聯繫,這個聯繫先理解爲外鍵,這兩個表就能夠叫作關聯表,能夠是多對一,多對多,一對一
Django 1.7 爲咱們帶來了三個新命令:php
migrate: 用於執行遷移動做html
makemigrations: 基於當前的model建立新的遷移策略文件python
sqlmigrate: 顯示遷移的SQL語句mysql
值得注意的是, migration是基於App的, 所以, 咱們能夠針對某些app不啓用migration功能.web
migrations的使用很是簡單: 修改model, 好比增長field, 而後運行sql
python manager.py makemigrations
你的mmodel會被掃描, 而後與以前的版本做比較, 在app的migrations目錄下生成本次遷移文件.shell
咱們建議查看一下該遷移文件, 確保沒有問題. 而後運行:數據庫
python manager.py migrate
migrate命令會進行比較, 並應用該遷移.django
Django的標準庫存放在 django.contrib 包中。每一個子包都是一個獨立的附加功能包。 這些子包通常是互相獨立的,不過有些django.contrib子包須要依賴其餘子包。數組
在 django.contrib 中對函數的類型並無強制要求 。其中一些包中帶有模型(所以須要你在數據庫中安裝對應的數據表),但其它一些由獨立的中間件及模板標籤組成。
django.contrib 開發包共有的特性是: 就算你將整個django.contrib開發包刪除,你依然可使用 Django 的基礎功能而不會遇到任何問題。 當 Django 開發者向框架增長新功能的時,他們會嚴格根據這一原則來決定是否把新功能放入django.contrib中。
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',
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 settings
url(r"^uploads/(?P<path>.*)$", \ "django.views.static.serve", \ {"document_root": settings.MEDIA_ROOT,}),
KindEditor.ready(function(K) { K.create('textarea[name=content]',{ width:800, height:200, }); });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自帶的去重複方法,對整個字段進行去重
三、django中直接使用sql的兩種方式 SELECT DISTINCT DATE_FORMAT(date_publish, '%Y-%m') as col_date FROM blog_article ORDER BY date_publish 3.一、raw (異常:Raw query must include the primary key,返回結果必須包含主鍵) 3.二、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 }}