用django写个CMS系统
上一篇介绍过django自带的flatpages,能够做简单的CMS。但是对于我们的真正的工作中的使用意义并不大。还是自己动手写一个吧。
不用说,一定是先从models开始的:
from django.db import models # Create your models here. from django.contrib.auth.models import User
from django.db.models import permalink
from markdown import markdown
from django.utils import timezone
from DjangoUeditor.models import UEditorField VIEWABLE_STATUS=[3,4] class ViewableManager(models.Manager):
def ge_query_set(self):
default_queryset = super(ViewableManager,self).get_queryset()
return default_queryset.filter(status__in = VIEWABLE_STATUS) class Story(models.Model):
STATUS_CHOICES= (
(1,"Need Edit"),
(2,"Need Approval"),
(3,"Published"),
(4,"Archived"),
)
title = models.CharField(max_length=100)
slug = models.SlugField()
category = models.ForeignKey("Category")
markdown_content = UEditorField('内容', height=300, width=1000,
default=u'', blank=True, imagePath="uploads/images/",
toolbars='besttome', filePath='uploads/files/')
html_content = models.TextField(editable=False)
owner = models.ForeignKey(User)
status = models.IntegerField(choices=STATUS_CHOICES,default=1)
created = models.DateTimeField(auto_now_add=True)
modified= models.DateTimeField(auto_now=True)
class Meta:
ordering =['modified']
verbose_name_plural= '新闻故事'
admin_objects = models.Manager()
objects = ViewableManager() def save(self,*args,**kwargs):
self.html_content = markdown(self.makedown_content)
self.modified= timezone.now()
super(Story,self).save(*args,**kwargs) @permalink
def get_absolute_url(self):
return ('cms-story',None,{'slug':self.slug}) def __str__(self):
return self.title class Category(models.Model):
label = models.CharField(max_length=64)
slug = models.SlugField() class Meta:
verbose_name_plural="分类" def __str__(self):
return self.label
model中有几个需要注意的地方:
1、自定义了Story类的manger,这个是为了在使用queryset的时候objects.all()等查询数据库时只显示已经发布或者存档的文章或新闻
2、修改了markdown_content为UEditorField字段,可能很多小伙伴没见过,表着急,这个后面会解释,可以先改成TextField字段
3、重写了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"),
]
好吧,路由分配系统写完了之后,就该开始写我们的试图了,我这里用了两个通用类试图,可能某些小伙伴不太习惯吧,你写成试图函数也可以的,用我们领导的经典语句:“嗯哼,这都没有关系~~~”。
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())
看看这些试图都干了些什么吧,展示文章列表,展示分类文章,展示文章详情,一个简单的查询。
前端页面的代码实在是懒得弄了,简单凑合一下吧
首先写一个母版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了,添加了一个富文本编辑器

实在是太困了,具体的做法以后再细说吧,网上也有很多这种的教程,自己搜一个吧
用django写个CMS系统的更多相关文章
- Django写的投票系统2(转)
在上一篇中 django实例:创建你的第一个应用投票系统(一) 已经介绍基本的功能,并已经启动服务了.这一节介绍数据库相关的东东. 首页打开mysite/settings.py配置文件, 设置数据库打 ...
- Django写的投票系统4(转)
原文地址:http://www.cnblogs.com/djangochina/archive/2013/06/04/3114269.html 现在已经可以在后台管理投票了,现在就差怎么在前台显示和如 ...
- Django写的投票系统3(转)
Django的管理面板默认是不开启的,所以我们需要进行一些设置工作1.在INSTALLED_APPS里面把 django.contrib.admin 前面的注释去掉2.运行 python manage ...
- Django写的投票系统1(转)
当然主要是从django的帮助文档里面来的,权当是翻译吧 这个投票系统的主要功能有 1.一个前台页面,可以让用户来投票 2.一个管理员页面,可以用来添加.修改.删除投票 首页第一步要确定你已经安装了D ...
- django的CMS系统(内容管理系统)
一.什么是CMS系统 CMS具有许多基于模板的优秀设计,可以减少开发的成本. CMS的功能并不只限于文本处理,它也可以处理图片.Flash动画.声像流.图像甚至电子邮件档案. CMS还分各个平台脚本种 ...
- 《全栈营销之如何制作个人博客》之一:用什么开发语言和CMS系统
现在的互联网,已经不再是初级互联时代,是需要全方位营销,自建粉丝池的时代,云码素材从提出全栈营销,到实践分析,总结出全栈营销第一步,先制作一个个人博客是最好的开始.今天开始就跟我一起学习如何制作一个精 ...
- 一个基于NodeJS开发的APP管理CMS系统
花了大概3周独立开发了一个基于NodeJS的CMS系统,用于公司APP的内容管理( **公司APP?广告放在最后 ^_^ ** ,管理员请理解~~~ )晚上看了部电影还不想睡,闲着也是闲着就作下小小总 ...
- Laravel系列之CMS系统学习 — 角色、权限配置【2】
一.RBAC分析 基于角色的权限访问控制(Role-Based Access Control),这里存在这么几个玩意儿:角色.权限,用户 表:roles.permissions.role_has_pe ...
- CMS系统简介(从简介到使用)
CMS系统简介 1.简介 CMS是Content Management System的缩写,意为"内容管理系统". 在中国互联网的发展历程中,一直以来默默地为中国站长提供动力的CM ...
随机推荐
- js将用户上传gif动图分解成多张帧图片
js将用户上传gif动图分解成多张帧图片 写在前面 工作中遇到一个这么一个需求:这是一个多图上传的场景,如果用户上传选择多张图片,则上传后直接展示多张图片,如果上传的图片是gif动图,则需要分解这张动 ...
- bzoj1670【Usaco2006 Oct】Building the Moat 护城河的挖掘
1670: [Usaco2006 Oct]Building the Moat护城河的挖掘 Time Limit: 3 Sec Memory Limit: 64 MB Submit: 387 Sol ...
- wxPython 4.0.0b2安装
https://www.cnblogs.com/NanShan2016/p/5518235.html 亮的界面是一个GUI程序必不可少的一部分,wxPython可以做到这一点,加之Python强大的功 ...
- Mysql数据库分库备份,分表备份
分库备份 #!/bin/sh DBPATH=/server/backup MYUSER=root MYPASS=oldboy123 SOCKET=/data/3306/mysql.sock MYCMD ...
- mysql bin-log三种模式
MySQL的bin-log日志备份有三种模式,分别是:ROW.Statement.Mixed 一.Row 日志会记录成每一行数据被修改成的形式,然后再slave端再对相同的数据进行修改,只记录要修改的 ...
- codeforces #364a Cards
cf的a题没什么好说到,100的量级,每个人给2张牌,使每个人手中的牌点数相等.保证有一种分配方案. 对每个人,先计算出手中的牌的点数,然后循环两遍拿牌就可以. A. Cards time lim ...
- Codeforces 460E Roland and Rose(暴力)
题目链接:Codeforces 460E Roland and Rose 题目大意:在以原点为圆心,半径为R的局域内选择N个整数点,使得N个点中两两距离的平方和最大. 解题思路:R最大为30.那么事实 ...
- hdu5794 A Simple Chess 容斥+Lucas 从(1,1)开始出发,每一步从(x1,y1)到达(x2,y2)满足(x2−x1)^2+(y2−y1)^2=5, x2>x1,y2>y1; 其实就是走日字。而且是往(n,m)方向走的日字。还有r个障碍物,障碍物不可以到达。求(1,1)到(n,m)的路径条数。
A Simple Chess Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- 【Mac + ATX基于uiautomator2】使用weditor时,报错:requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(54, 'Connection reset by peer'))
产生以下原因找到了:是因为启动了appium,两者冲突,不能同时使用. 之前讲过怎么安装u2([Mac安装,ATX基于uiautomator2]之安装步骤)以及使用weditor, 但是经过一段时间, ...
- input type="file"文件上传时得到文件的本地路劲
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <meta name=& ...