用django寫個CMS系統

上一篇介紹過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了,添加了一個富文本編輯器

 

 

實在是太困了,具體的作法之後再細說吧,網上也有不少這種的教程,本身搜一個吧

相關文章
相關標籤/搜索