这个博客是一个复习项目,有几天没做django了,因为之前一直用django1.8.3做的,现在改用django1.11.2,这也出现了一些版本上的问题,尤其是集成编辑器的时候
开始吧:
pip install virtualenv virtualenvwrapper-win
mkvirtualenv blog
pip install Django==1.11.2
django-amdin startproject lian1
cd lian1
python manange.py blog
开始写model.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.conf import settings
from django.db import models
from DjangoUeditor.models import UEditorField
#全局状态设置
STATUS={
0:u'正常',
1: u'草稿',
2: u'删除',
}
#创建博客分类
class Category(models.Model):
name = models.CharField(max_length=40,verbose_name=u'分类')
rank = models.IntegerField(default=0,verbose_name=u'分类排序')
status = models.IntegerField(default=0,verbose_name=u'状态')
create_time = models.DateTimeField(u'创建时间',auto_now_add=True)
class Meta:
verbose_name_plural=verbose_name='分类'
ordering=['rank','-create_time']
def __unicode__(self):
return self.name
#创建博客文章
class Article(models.Model):
title=models.CharField(max_length=60,verbose_name=u'标题')
category =models.ForeignKey(Category,verbose_name=u'分类')
author= models.ForeignKey(settings.AUTH_USER_MODEL,verbose_name=u'作者')
tags = models.CharField(max_length=60,verbose_name=u'标签')
summary = models.TextField(verbose_name=u'摘要')
content=UEditorField('详情', height=300, width=1000,
default=u'', blank=True, imagePath="uploads/images/",
toolbars='besttome', filePath='uploads/files/')
img = models.ImageField(upload_to='upload')
status = models.IntegerField(default=0, choices=STATUS.items(), verbose_name=u'状态')
is_top = models.BooleanField(default=False,verbose_name=u'置顶')
rank =models.IntegerField(default=0,verbose_name=u'排序')
pub_time = models.DateTimeField(default=False, verbose_name=u'发布时间')
update_time= models.DateTimeField(u'更新时间',auto_now=True)
create_time = models.DateTimeField(u'创建时间', auto_now_add=True)
def get_tags(self):
return self.tags.split(',')#标签的使用
class Meta:
verbose_name_plural=verbose_name=u'文章'
ordering=['rank','is_top','-pub_time','-create_time']
def __unicode__(self):
return self.title
class Comment(models.Model):
blog = models.ForeignKey(Article,verbose_name='博客')
name=models.CharField('称呼',max_length=16)
email=models.EmailField('邮箱')
content=models.CharField('内容',max_length=240)
pub=models.DateField('发布时间',auto_now_add=True)
class Meta:
verbose_name_plural=verbose_name='评论'
def __unicode__(self):
return self.content
开始写admin.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from blog.models import Article,Category,Comment
from django.contrib import admin
# Register your models here.
class CategoryAdmin(admin.ModelAdmin):
search_fields=('name',)
list_filter = ('status','create_time')
list_display = ('name','rank','status')
fields = ('name','rank','status')
class ArticleAdmin(admin.ModelAdmin):
search_field=('title','summary')
list_filter = ('status','category','is_top','create_time','update_time')
list_display=('title','category','author','status','is_top','update_time')
fieldsets = (
(u'基本信息',{'fields':('title','category','author','status','is_top','tags','img')}),
(u'内容',{'fields':('content',)}),
(u'摘要',{'fields':('summary',)}),
(u'时间',{'fields':('pub_time',)})
)
class CommentAdmin(admin.ModelAdmin):
list_display =('blog','name','content','pub')
admin.site.register(Comment,CommentAdmin)
admin.site.register(Article,ArticleAdmin)
admin.site.register(Category,CategoryAdmin)
这些写好后开始集成DjangoUeditor,但是由于版本的问题,需要修改DjangoUeditor文件的urls.py
DjangoUeditor/urls.py(这是修改后的)
#coding:utf-8
from django import VERSION
if VERSION[0:2] > (1, 9):
from django.conf.urls import url
elif VERSION[0:2] > (1, 3):
from django.conf.urls import patterns, url
else:
from django.conf.urls.defaults import patterns, url
from views import get_ueditor_controller
if VERSION[0:2] > (1, 9):
urlpatterns = [
url(r'^controller/$', get_ueditor_controller)
]
else:
urlpatterns = patterns('',
url(r'^controller/$', get_ueditor_controller)
)
增加forms.py表单验证
#coding:utf-8
from django import forms
class CommentForm(forms.Form):
name=forms.CharField(label='称呼',max_length=16,error_messages={
'required':'请填写您的称呼',
'max_length':'称呼太长咯'
})
email=forms.EmailField(label='邮箱',error_messages={
'required':'请填写您的邮箱',
'invalid':'邮箱格式不正确'
})
content=forms.CharField(label='内容',error_messages={
'required':'请填写您的评论内容!',
'max_length':'评论内容太长咯'
})
然后修改lian1/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from django.conf import settings
from DjangoUeditor import urls as DjangoUeditor_urls
from blog.views import *
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'ueditor/', include(DjangoUeditor_urls)),
url(r'^index/$',get_blogs),
url(r'^detail/(\d+)/$',get_details,name='detail'),
]
if settings.DEBUG:
from django.conf.urls.static import static
urlpatterns += static(
settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
设置静态,修改settings.py
"""
Django settings for lian project.
Generated by 'django-admin startproject' using Django 1.11.2.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
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.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'mxts#+l%!xo07v8k%l1+*2cjmcn%#q9b^7)+v5mrxjx$++zvwf'
# 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',
'blog',
'DjangoUeditor',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'lian.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 = 'lian.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/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.11/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.11/topics/i18n/
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT=os.path.join(BASE_DIR,'static')
STATICFILES_DIRS=(os.path.join(BASE_DIR,'common_static'),)
MEDIA_URL = '/upload/'
MEDIA_ROOT =os.path.join(BASE_DIR,'upload')
开始写views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render,render_to_response
from django import template
from django.http import HttpResponse,Http404
from django.views.generic import ListView
from blog.models import *
from .models import *
from django.conf import settings
from .forms import CommentForm
# Create your views here.
def get_blogs(request):
blogs = Article.objects.all()
return render_to_response('index.html',{'blogs':blogs})
def get_details(request,blog_id):
#检查异常
try:
blog=Article.objects.get(id=blog_id)#获取固定的blog_id的对象;
except Article.DoesNotExist:
raise Http404
if request.method =='GET':
form =CommentForm()
else:
form =CommentForm(request.POST)
if form.is_valid():
cleaned_data=form.cleaned_data
cleaned_data['blog']=blog
Comment.objects.create(**cleaned_data)
ctx={
'blog':blog,
'comments':blog.comment_set.all().order_by('-pub'),
'form':form
}#返回3个参数
return render(request,'details.html',ctx)
因为只是复习,模板就不写了,能调用出来就行了
index.html:
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
{% for blog in blogs %}
<a href="{% url 'detail' blog.id %}">{{ blog.title }}</a>
<img src="/upload/{{ blog.img }}"/>
{{ blog.tags }}{{ blog.category }}{{ blog.author }}{{ blog.pub_time }}
{{ blog.summary | truncatechars:100 }}
{% endfor %}
</body>
</html>
details.html:
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ blogs.title }}</title>
</head>
<body>
<div class="title">
<a href="#"><h2>{{ blogs.title }}</h2></a>
</div>
<div class="info">
<span class="category" style="color:#ff9900 ;">{{ blogs.category.name }}</span>
<span class="author" style="color: #4a86e8">{{ blogs.author }}</span>
<span class="pub" style="color: #6aa84f">{{ blog.pub_time }}</span>
</div>
<div class="summary">
{% autoescape off%}
{{blog.content}}
{% endautoescape %}
</div>
<h2>评论</h2>
{% for comment in comments %}
{{ comment.name }}说:{{ comment.content }}
{% endfor %}
<h3>提交评论</h3>
<form action="{% url 'detail' blog.id %}" method="'post">
{% csf_token %}
{% for field in form %}
{{ field.label }}:{{ field }}
{{ field.errors }}
<button type="submit" style="margin-top:10px ">提交</button>
<input type="button" value="返回">
{% endfor %}
</form>
</body>
</html>
虽然是简单的项目,但是似乎对views的使用上还是不熟悉,用了一个下午才做出来。后面要加强的部分。。