美文网首页
Django从零搭建CMS(内容管理)系统

Django从零搭建CMS(内容管理)系统

作者: lbcBoy | 来源:发表于2019-12-06 21:43 被阅读0次

本教程分为三部分:思路、详细步骤、开发步骤,从上往下看,便于理解;

思路:

  • 1.准备开发环境
  • 2.学习基本的Django基础知识、搭建简单的polls系统
  • 3.确定练手题材,比如我确定了做个家用的菜谱
  • 4.寻找合适的html模板
  • 5.根据网站需要添加学习添加新的数据类型,比如添加图片上传、添加富文本编辑
  • 6.Windows下部署Django(Apache+mod_wsgi)
  • 7.linux下部署Django(todo)

注意:没有接触过Django但是接触过python的情况下,完成前6步,大概需要2天的时间。

Django常用命令:
简单启动:python manage.py runserver
创建应用:python manage.py startapp xxx
检查app并创建相应的表:python manage.py migrate
激活model-生成sql:python manage.py makemigrations food
激活model-执行sql:python manage.py sqlmigrate food 0001
激活model-再次执行:python manage.py migrate

详细步骤

1.准备开发环境

主要涉及pythonCharm的安装、python3的安装,自己找教程搞定;

2.学习基本的Django基础知识、搭建简单的polls系统

参考官方文档:https://docs.djangoproject.com/zh-hans/2.1/
完成快速入门部分的学习,基本就能了解django的工作原理,各个文件的作用,并搭建一个简单的投票系统;

image.png

3.确定练手题材

根据第2步中学习的知识,自己做一个全新的网站。第一个网站不要太难,建议选择CMS(内容管理系统),我在选择的是家用菜谱。

功能需求:
- 管理后台可以新增、修改、删除菜单
- 编辑好的菜单,可以在页面显示
- 菜单参考饭店的二维码点餐目录:全部菜单、主食、素材、汤等

非功能性需求:
- 界面简洁美观,最好能自适应

二期拓展:
- 菜单可以评论
- 添加日历,记录当然的菜品或事件
- 优化后端界面操作等(xadmin)

4.寻找合适的html模板

我自己没有非常好的前端基础,如果从零写一套美观的界面,非常耗时且不能保证效果。所以我希望使用已有的前端模板,整合到Django中,略做调整就可以使用。
后来我从网上找了适合自己题材的模板:http://sc.chinaz.com/tag_moban/Html.html
下图是我选用的模板(链接:http://sc.chinaz.com/moban/180521171540.htm):

image.png

将模板整合到项目相应app的templates中去:


image.png

5.根据网站需要添加新的数据类型Ueditor、ImageField

菜单的内容肯定是图文的,所以我整合了Ueditor
    content = UEditorField('内容', height=300, width=800, max_length=1024000000000,
                           default=u'', blank=True, imagePath="food/ueditor/images/",
                           toolbars='besttome', filePath='food/ueditor/files/')

菜单的索引页需要一张封面图片,所以我添加了图片上传功能;
    show_pic = models.ImageField('照片', upload_to="food/ueditor/images/", blank=True, null=True)

6.Windows下部署Django(Apache+mod_wsgi)

在自己的电脑上部署一个局域网内的菜谱系统;

开发步骤

1.根据详细步骤-2走完之后,你的系统里面已经有一个叫polls的应用,可以添加问题、选项、可以投票;

image.png

2.创建我自己的应用food

2.1.创建food应用

python manage.py startapp food

2.2.确定文章内容的字段、确定model Article,只有一个model,刚开始所有的类型都用CharField

create_time、update_time、title、sub_title、article_type、author、key_word、show_pic、content

2.3.检查app并创建相应的表

python manage.py migrate

2.4.激活model

settings.py中添加:'food.apps.FoodConfig',
准备sql:python manage.py makemigrations food
执行sql:python manage.py sqlmigrate food 0001
再次执行:python manage.py migrate

2.5.管理后台中编译一条记录,然后再让它在页面中显示,可以显示title就可以了
2.6.修改model Article的字段-show_pic

首先将封面照片show_pic = models.CharField(max_length=50, null=True)
改为show_pic = models.ImageField('照片', upload_to="food/ueditor/images/", blank=True, null=True)
改完之后要做以下操作,才能生效(每次改完model都要这么执行):
激活model-生成sql:python manage.py makemigrations food
激活model-执行sql:python manage.py sqlmigrate food 0002
激活model-再次执行:python manage.py migrate

这里要注意settings中的static_url/static_root/media_url/media_root要先设置好
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

文件上传后,会根据media_url和models.ImageField中的upload_to,确定图片的保存路径,如图:

image.png

2.7.上传的文件需要正常显示,必须设置好url:

    # 媒体文件想要通过ip地址访问到静态文件要做如下配置
    url(r'^media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}, name='media')

2.8.修改model Article的字段-content
2.8.1)下载DjangoUeditor:
python3: https://github.com/twz915/DjangoUeditor3/ (直接下载zip)

2.8.2)在项目的根目录新建extra_apps文件夹并将我们下载好的zip文件解压,
打开后找到 DjangoUeditor将DjangoUeditor直接拷贝到我们项目的extra_apps中,如图:

image.png

2.8.3)在settings.py文件中添加两行代码:如下

  sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
  sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))

2.8.4)通过pycharm 选中extra_apps文件夹点击鼠标右键选中菜单mark directory as 选择 sources root就可以变成上面的蓝色文件夹目录就可以了。

2.8.5)变成蓝色文件夹后就可以在settings.py 的INSTALLED_APPS中引入DjangoUeditor,如下:

INSTALLED_APPS = [
   'polls.apps.PollsConfig',
   'food.apps.FoodConfig',

   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
   'DjangoUeditor',
]

2.8.6)在的settings同级的urls.py中添加ueditor:

    path('ueditor/', include('DjangoUeditor.urls')),

2.8.7) 将content改成Ueditor

 content = UEditorField('内容', height=300, width=800, max_length=1024000000000,
                           default=u'', blank=True, imagePath="food/ueditor/images/",
                           toolbars='besttome', filePath='food/ueditor/files/')

改完之后要做以下操作,才能生效(每次改完model都要这么执行):
激活model-生成sql:python manage.py makemigrations food
激活model-执行sql:python manage.py sqlmigrate food 0002
激活model-再次执行:python manage.py migrate

2.8.8)问题:Ueditor的图片不展示
因为img的src 没有域名,确保DjangoUeditor中的views.py244行,数据返回的格式正确,如图:

image.png

2.9.Html迁移相关问题
注意1目录分布


image.png

注意2css的相对路径

<link rel="stylesheet" href="../../static/food/css/bootstrap.min.css">

注意3左侧li选中active效果

               <li {% if request.path == '/food/' %}
                    class="probootstrap-animate active"
                {% else %}
                    class="probootstrap-animate"
                {% endif %} data-animate-effect="fadeInLeft">
                    <a href={% url 'food:index' %}>全部菜单</a>
                </li>

2.10.相关代码参考
2.10.1food应用下的models

import datetime
from django.db import models
# Create your models here.
from django.utils import timezone
from DjangoUeditor.models import UEditorField
class Article(models.Model):
    create_time = models.DateTimeField('创建时间')
    update_time = models.DateTimeField('更新时间')

    title = models.CharField(max_length=100, null=True)
    sub_title = models.CharField(max_length=100, null=True)
    article_type = models.CharField(max_length=50, null=True)
    author = models.CharField(max_length=50, null=True)
    key_word = models.CharField(max_length=50, null=True)
    # show_pic = models.CharField(max_length=50, null=True)
    # show_pic = models.ImageField(upload_to="icons", height_field='url_height', width_field='url_width')
    show_pic = models.ImageField('照片', upload_to="food/ueditor/images/", blank=True, null=True)

    content = UEditorField('内容', height=300, width=800, max_length=1024000000000,
                           default=u'', blank=True, imagePath="food/ueditor/images/",
                           toolbars='besttome', filePath='food/ueditor/files/')

    def show_pic_url(self):
        if self.show_pic and hasattr(self.show_pic, 'url'):
            return self.show_pic.url
        else:
            return '/media/default/user.jpg'

    def __str__(self):
        return self.title

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.update_time <= now

    was_published_recently.admin_order_field = 'update_time'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

2.10.2food应用下的urls.py


from food import views
from food.views import page_not_found

app_name = 'food'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('staple_food', views.StapleFoodView.as_view(), name='staple_food'),
    path('half', views.HalfOfMeat.as_view(), name='half'),
    path('big', views.BigMeat.as_view(), name='big'),
    path('vegetable', views.Vegetable.as_view(), name='vegetable'),
    path('soup', views.Soup.as_view(), name='soup'),
    path('cold', views.Cold.as_view(), name='cold'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
]


# 定义错误跳转页面
# handler403 = permission_denied
handler404 = page_not_found
# handler500 = page_error

2.10.3food应用下的views.py

# Create your views here.
from django.shortcuts import render
from django.views import generic
from food.models import Article

class IndexView(generic.ListView):
    template_name = 'food/index.html'
    context_object_name = 'latest_article_list'

    def get_queryset(self):
        """Return the last five published questions."""
        print(Article.objects.all())
        return Article.objects.all()
        # return Article.objects.filter(update_time__lte=timezone.now()).order_by('-update_time')[:5]

class DetailView(generic.DetailView):
    model = Article
    template_name = 'food/detail.html'

class StapleFoodView(generic.ListView):
    template_name = 'food/index.html'
    context_object_name = 'latest_article_list'

    def get_queryset(self):
        """Return the last five published questions."""
        print(Article.objects.all())
        return Article.objects.filter(article_type__contains="staple")

class HalfOfMeat(generic.ListView):
    template_name = 'food/index.html'
    context_object_name = 'latest_article_list'

    def get_queryset(self):
        """Return the last five published questions."""
        print(Article.objects.all())
        return Article.objects.filter(article_type__contains="half")

class BigMeat(generic.ListView):
    template_name = 'food/index.html'
    context_object_name = 'latest_article_list'

    def get_queryset(self):
        """Return the last five published questions."""
        print("大荤:")
        print(Article.objects.filter(article_type__contains="big"))
        return Article.objects.filter(article_type__contains="big")

# 素菜
class Vegetable(generic.ListView):
    template_name = 'food/index.html'
    context_object_name = 'latest_article_list'

    def get_queryset(self):
        """Return the last five published questions."""
        print(Article.objects.all())
        return Article.objects.filter(article_type__contains="vegetable")

# 凉菜
class Cold(generic.ListView):
    template_name = 'food/index.html'
    context_object_name = 'latest_article_list'

    def get_queryset(self):
        """Return the last five published questions."""
        print(Article.objects.all())
        return Article.objects.filter(article_type__contains="cold")

# 汤
class Soup(generic.ListView):
    template_name = 'food/index.html'
    context_object_name = 'latest_article_list'

    def get_queryset(self):
        """Return the last five published questions."""
        print(Article.objects.all())
        return Article.objects.filter(article_type__contains="soup")

# 全局403、404、500错误自定义页面显示
def page_not_found(request):
    return render(request, 'food/404.html')
def page_error(request):
    return render(request, '500.html')
def permission_denied(request):
    return render(request, '403.html')

2.10.4food应用下的admin.py

from django.contrib import admin

# Register your models here.
from food.models import Article


class ArticleAdmin(admin.ModelAdmin):
    fields = ['create_time', 'update_time', 'title', 'sub_title', 'article_type', 'author', 'key_word', 'show_pic',
              'content']
    list_display = ('create_time', 'update_time', 'title', 'sub_title', 'article_type', 'author', 'key_word', 'show_pic')

admin.site.register(Article, ArticleAdmin)

3.Windows下部署Django(Apache+mod_wsgi)

详细步骤参考:https://www.jianshu.com/p/598d8b5fbee6

注意的问题:
1.Apache24安装后启动不起来
    1)、在cmd命令行进入Apache24/bin目录下
    2)、执行httpd -t命令
    3)、会看到错误提示:(仅仅是我的情况)AH00526:
 Syntax error on line 34 of F:/Apache/Apache/conf/extra/httpd-ahssl.conf:SSLProtocol: Illegal protocol 'TLSv1.3'
    4)、先进入到这个文件改34行,SSLProtocol -all +TLSv1.2 +TLSv1.3发现怎么改都没有用,看了下他的上一行
    把<IfDefine ENABLE_TLS13>改成<IfDefine ENABLE_TLS12>问题解决了

2.mod_wsgi的安装、检查最好在cmd中,否则mod_wsgi-express module-config出现不了3条准确的记录;再pythonCharm的terminal执行只有2条记录;
3.Django已经安装,而且pythonCharm运行的时候正常,但是windows下部署,apache的错误日志中提示Django未安装:
windows下部署,注意pythoncharm中安装的django路径可能和python不一样;需要在命令行重新安装;注意安装的时候指定版本;

效果图


image.png image.png

4.部署到linux

TODO

相关文章

网友评论

      本文标题:Django从零搭建CMS(内容管理)系统

      本文链接:https://www.haomeiwen.com/subject/tubkgctx.html