美文网首页
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