上一篇介紹過django自帶的flatpages,可以作簡單的CMS。可是對於咱們的真正的工做中的使用意義並不大。仍是本身動手寫一個吧。html
不用說,必定是先從models開始的:前端
1 from django.db import models 2 3 # Create your models here. 4 5 from django.contrib.auth.models import User 6 from django.db.models import permalink 7 from markdown import markdown 8 from django.utils import timezone 9 from DjangoUeditor.models import UEditorField 10 11 VIEWABLE_STATUS=[3,4] 12 13 14 class ViewableManager(models.Manager): 15 def ge_query_set(self): 16 default_queryset = super(ViewableManager,self).get_queryset() 17 return default_queryset.filter(status__in = VIEWABLE_STATUS) 18 19 20 class Story(models.Model): 21 STATUS_CHOICES= ( 22 (1,"Need Edit"), 23 (2,"Need Approval"), 24 (3,"Published"), 25 (4,"Archived"), 26 ) 27 title = models.CharField(max_length=100) 28 slug = models.SlugField() 29 category = models.ForeignKey("Category") 30 markdown_content = UEditorField('內容', height=300, width=1000, 31 default=u'', blank=True, imagePath="uploads/images/", 32 toolbars='besttome', filePath='uploads/files/') 33 html_content = models.TextField(editable=False) 34 owner = models.ForeignKey(User) 35 status = models.IntegerField(choices=STATUS_CHOICES,default=1) 36 created = models.DateTimeField(auto_now_add=True) 37 modified= models.DateTimeField(auto_now=True) 38 class Meta: 39 ordering =['modified'] 40 verbose_name_plural= '新聞故事' 41 admin_objects = models.Manager() 42 objects = ViewableManager() 43 44 def save(self,*args,**kwargs): 45 self.html_content = markdown(self.makedown_content) 46 self.modified= timezone.now() 47 super(Story,self).save(*args,**kwargs) 48 49 @permalink 50 def get_absolute_url(self): 51 return ('cms-story',None,{'slug':self.slug}) 52 53 def __str__(self): 54 return self.title 55 56 57 class Category(models.Model): 58 label = models.CharField(max_length=64) 59 slug = models.SlugField() 60 61 class Meta: 62 verbose_name_plural="分類" 63 64 def __str__(self): 65 return self.label
model中有幾個須要注意的地方:數據庫
一、自定義了Story類的manger,這個是爲了在使用queryset的時候objects.all()等查詢數據庫時只顯示已經發布或者存檔的文章或新聞django
二、修改了markdown_content爲UEditorField字段,可能不少小夥伴沒見過,表着急,這個後面會解釋,能夠先改爲TextField字段markdown
三、重寫了save方法,在保存數據的時候生成html_content編輯器
接下來是url函數
from django.views.generic import ListView,DetailView from cms.views import category,StoryDetailView,StoryListView,search urlpatterns = [ url(r'^$',StoryListView.as_view(),name="cms-home"), url(r'^story/(?P<slug>[-_\w]+)/$',StoryDetailView.as_view(),name="cms-story"), url(r'^category/(?P<slug>[-_\w]+)/$',category,name="cms-category"), url(r'^search/$',search,name="cms-search"), ]
好吧,路由分配系統寫完了以後,就該開始寫咱們的試圖了,我這裏用了兩個通用類試圖,可能某些小夥伴不太習慣吧,你寫成試圖函數也能夠的,用咱們領導的經典語句:「嗯哼,這都沒有關係~~~」。url
from django.shortcuts import render,get_object_or_404,render_to_response from django.db.models import Q from cms.models import Category,Story from django.views.generic import ListView,DetailView # Create your views here. def category(request,slug): category_obj = get_object_or_404(Category,slug=slug) story_list = Story.objects.filter(category=category_obj) heading = "Category:%s"%category_obj.label return render(request,'cms/story_list.html',locals()) class StoryListView(ListView): model = Story template_name = 'cms/story_list.html' context_object_name = "story_list" class StoryDetailView(DetailView): model = Story template_name = "cms/story_detail.html" context_object_name = "story" def search(request): print(request.GET) if 'q' in request.GET: term = request.GET.get('q') story_list = Story.objects.filter(Q(title__icontains=term)|Q(makedown_content__icontains=term)).all() heading = "檢索結果" return render(request,"cms/story_list.html",locals())
看看這些試圖都幹了些什麼吧,展現文章列表,展現分類文章,展現文章詳情,一個簡單的查詢。spa
前端頁面的代碼實在是懶得弄了,簡單湊合一下吧code
首先寫一個母版base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}{% endblock %}</title> <style> body{margin: 15px; font-family: "Arial Black"; } h1,h2{background: #aaa; padding: 1% 2%; margin: 0; } a{text-decoration: none; color: #444; } .small{ font-size: 75%; color: #777; } #header{ font-weight: bold;background: #ccc;padding: 1% 2%; } #story_body{ background: #ccc; padding: 2%; } #story_list{ background: #ccc; padding: 1% 1% 1% 2%; } #story_list li{ margin: 0.5em 0; } </style> </head> <body> <div id="header"> <form action="{% url 'cms-search' %}" method="get"> <a href="{% url 'cms-home' %}">Home</a> <span style="padding: 0 50px"></span> <label for="q">Search</label><input type="text" name="q"/> </form> </div> {% block content %}{% endblock %} </body> </html>
接下來是文章列表的展現了cms/story_list.html
{% extends "base.html" %} {% block title %} {{ heading }} {% endblock %} {% block content %} {% if heading %} <h1>{{ heading }}</h1> {% endif %} <ul id="story_list"> {% for story in story_list %} <li><a href="{{ story.get_absolute_url }}">{{ story.title }}</a></li> {% endfor %} </ul> {% endblock %}
最好不要把html中的url寫死了,方便你之後的擴展或修改
接下來是文章詳情展現
{% extends "base.html" %} {% block title %} {{ story.title }} {% endblock %} {% block content %} <h1>{{ story.title }}</h1> <h2><a href="{% url "cms-category" story.category.slug %}">{{ story.category }}</a></h2> <div id="story-body"> {{ story.html_content|safe }} <p class="small">{{ story.modified }}</p> </div> {% endblock %}
效果圖
最後在來解釋一下model中的UEditorField字段,這個是由於我以爲admin後臺的text文本框字段太low了,添加了一個富文本編輯器
實在是太困了,具體的作法之後再細說吧,網上也有不少這種的教程,本身搜一個吧