13-day08-项目开发-wiki开发(添加、多级目录、预览)

一、wiki表结构设计

ID 标题 内容 项目ID 父ID
1 xx 你好呀 1 null
2 haha ffff 1 null
3 hehe fsd 1 1
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/models.py 

...
...
class Wiki(models.Model):
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    title = models.CharField(verbose_name='标题', max_length=32)
    content = models.TextField(verbose_name='内容', null=True)

    # 子关联父文章ID (可以写此表名称或者self,都表示子关联)
    # 反向关联字段 related_name 表示反向查找使用的字段名称
    parent = models.ForeignKey(verbose_name='父文章', to="Wiki", null=True, blank=True, related_name='children',on_delete=models.CASCADE)
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % python3 manage.py makemigrations

Migrations for 'web_app':
  web_app/migrations/0005_wiki.py
    - Create model Wiki

(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % python3 manage.py migrate       
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, users_app, web_app
Running migrations:
  Applying web_app.0005_wiki... OK

二、wiki首页展示

  • 第一步 :url 路由设计
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/urls.py 

from django.conf.urls import url, include
from web_app.views import account
from web_app.views import home
from web_app.views import project
from web_app.views import manage
from web_app.views import wiki

...
...


    url(r'^manage/(?P<project_id>\d+)/', include([
        url(r'^dashboard/$', manage.dashboard, name='dashboard'),
        url(r'^file/$', manage.file, name='file'),
        url(r'^setting/$', manage.setting, name='setting'),
        url(r'^issues/$', manage.issues, name='issues'),
        url(r'^statistics/$', manage.statistics, name='statistics'),

        # url(r'^dashboard/issues/chart/$', manage.issues_chart, name='issues_chart'),
        #
        url(r'^wiki/$', wiki.wiki, name='wiki'),

    ], None)),

    # None 表示 反向代理的 namesapce,如果指定namesapce,前端请求此路由时就需要以{{% namespace_name:name%}} -> {{% haha:statistics_project_user%}}

]
  • 第二步 :Views视图
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/views/wiki.py 

from django.shortcuts import render

def wiki(request, project_id):
    """ wiki首页 """

    return render(request, 'wiki.html')
  • 第三步 :Template模板
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/templates/wiki.html 

{% extends 'layout/manage.html' %}

{% block css %}
    <style>
        .panel-default {
            margin-top: 10px;
        }
        
        .panel-body {
            padding: 0;
        }

        .title-list {
            border-right: 1px solid #dddddd;
            min-height: 500px;
        }

        .content {
            border-left: 1px solid #dddddd;
            min-height: 600px;
            margin-left: -1px;
        }

    </style>
{% endblock %}

{% block content %}
    <div class="container-fluid">

        <div class="panel panel-default">
            <div class="panel-heading"><i class="fa fa-book" aria-hidden="true"></i>wiki文档</div>
            <div class="panel-body">
                <div class="col-sm-3 title-list">
                    目录
                </div>
                <div class="col-sm-9 content">
                    内容
                </div>
        </div></div>
    </div>


{% endblock %}

image

  • 第四步 :继续优化Template,增加内容部署,展示提示项目信息
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/templates/wiki.html 

{% extends 'layout/manage.html' %}

{% block css %}
    <style>
        .panel-default {
            margin-top: 10px;
        }

        .panel-body {
            padding: 0;
        }

        .title-list {
            border-right: 1px solid #dddddd;
            min-height: 500px;
        }

        .content {
            border-left: 1px solid #dddddd;
            min-height: 600px;
            margin-left: -1px;
        }

    </style>
{% endblock %}

{% block content %}
    <div class="container-fluid">

        <div class="panel panel-default">
            <div class="panel-heading"><i class="fa fa-book" aria-hidden="true"></i>wiki文档</div>
            <div class="panel-body">
                <div class="col-sm-3 title-list">
                    目录
                </div>
                <div class="col-sm-9 content">
                    <div style="text-align: center;margin-top: 50px;">
                        <h4> 《{{ request.bug_manager.project.name }}》wiki文档库 </h4>
                        <a href="#">
                            <i class="fa fa-plus-circle" aria-hidden="true"></i> 新建文章
                        </a>
                    </div>
                </div>
        </div></div>
    </div>

{% endblock %}

image

三、wiki添加文章

3.1、wiki添加文章

  • 第一步:url添加文章路由设置
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/urls.py 

from django.conf.urls import url, include
from web_app.views import account
from web_app.views import home
from web_app.views import project
from web_app.views import manage
from web_app.views import wiki

...
...

    url(r'^manage/(?P<project_id>\d+)/', include([
        url(r'^dashboard/$', manage.dashboard, name='dashboard'),
        url(r'^file/$', manage.file, name='file'),
        url(r'^setting/$', manage.setting, name='setting'),
        url(r'^issues/$', manage.issues, name='issues'),
        url(r'^statistics/$', manage.statistics, name='statistics'),

        # url(r'^dashboard/issues/chart/$', manage.issues_chart, name='issues_chart'),
        #
        url(r'^wiki/$', wiki.wiki, name='wiki'),
        url(r'^wiki/add/$', wiki.wiki_add, name='wiki_add'),
    ], None)),

    # None 表示 反向代理的 namesapce,如果指定namesapce,前端请求此路由时就需要以{{% namespace_name:name%}} -> {{% haha:statistics_project_user%}}

]
  • 第二步 :Template,将前端新建文章绑定url
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/templates/wiki.html


{% extends 'layout/manage.html' %}

{% block css %}
    <style>
        .panel-default {
            margin-top: 10px;
        }

        .panel-default .panel-heading {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
        }

        .panel-body {
            padding: 0;
        }

        .title-list {
            border-right: 1px solid #dddddd;
            min-height: 500px;
        }

        .content {
            border-left: 1px solid #dddddd;
            min-height: 600px;
            margin-left: -1px;
        }

    </style>
{% endblock %}

{% block content %}
    <div class="container-fluid">

        <div class="panel panel-default">
            <div class="panel-heading">
                <div>
                    <i class="fa fa-book" aria-hidden="true"></i> wiki文档
                </div>
                <div class="function">
                    <a type="button" class="btn btn-success btn-xs"
                       href="{% url 'wiki_add' project_id=request.bug_manager.project.id %}">
                        <i class="fa fa-plus-circle" aria-hidden="true"></i> 新建
                    </a>

                </div>
            </div>


            <div class="panel-body">
                <div class="col-sm-3 title-list">
                    <div> 目录 </div>
                </div>

                <div class="col-sm-9 content">
                    <div style="text-align: center;margin-top: 50px;">
                        <h4> 《{{ request.bug_manager.project.name }}》wiki文档库 </h4>
                        <a href="{% url 'wiki_add' project_id=request.bug_manager.project.id %}">
                            <i class="fa fa-plus-circle" aria-hidden="true"></i> 新建文章
                        </a>
                    </div>
                </div>
                <div></div>
        </div>
        </div>
    </div>

{% endblock %}

image

  • 第三步 :wiki ModelForm,为wiki创建ModelForm
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/forms/wiki.py     

from django import forms
from web_app.forms.bootstrap import BootStrapForm
from web_app import models

class WikiModelForm(BootStrapForm, forms.ModelForm):

    #  model 定义元数据
    class Meta:
        # 对应的Model类
        model = models.Wiki
        # Model类中哪些字段可以展示,__all__ 表示所有
        # fields = '__all__' 也表示默认的展示顺序,可以手动指定展示顺序
        # exclude 排除哪些字段不展示
        exclude = ['project']   # 表示项目不进行展示

    # 重写__init__ 仅为在views视图调用Form初始化函数式多传递request参数
    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request
  • 第四步 :Views wiki添加视图
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/views/wiki.py 


from django.shortcuts import render
from web_app.forms.wiki import WikiModelForm

def wiki(request, project_id):
    """ wiki首页 """

    return render(request, 'wiki.html')

def wiki_add(request, project_id):
    """ wiki 文章添加 """
    form = WikiModelForm()
    return render(request, 'wiki_add.html', {'form': form})

  • 第五步 :Template 增加wiki添加的模板
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/templates/wiki_add.html 


{% extends 'layout/manage.html' %}

{% block css %}
    <style>
        .panel-default {
            margin-top: 10px;
        }

        .panel-default .panel-heading {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
        }

        .panel-body {
            padding: 0;
        }

        .title-list {
            border-right: 1px solid #dddddd;
            min-height: 500px;
        }

        .content {
            border-left: 1px solid #dddddd;
            min-height: 600px;
            margin-left: -1px;
        }

    </style>
{% endblock %}

{% block content %}
    <div class="container-fluid">

        <div class="panel panel-default">
            <div class="panel-heading">
                <div>
                    <i class="fa fa-book" aria-hidden="true"></i> wiki文档
                </div>
                <div class="function">
                    <a type="button" class="btn btn-success btn-xs"
                       href="{% url 'wiki_add' project_id=request.bug_manager.project.id %}">
                        <i class="fa fa-plus-circle" aria-hidden="true"></i> 新建
                    </a>

                </div>
            </div>


            <div class="panel-body">
                <div class="col-sm-3 title-list">
                    <div> 目录 </div>
                </div>

                <div class="col-sm-9 content">
                    <form method="post">
                        {% csrf_token %}
                        {% for field in form %}
                          <div class="form-group">
                              <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                              {{ field }}
                              <span class="error-msg">{{ field.errors.0 }}</span>
                          </div>
                        {% endfor %}
                          <button type="submit" class="btn btn-primary">提 交</button>
                    </form>

                </div>
                <div></div>
        </div>
        </div>
    </div>

{% endblock %}

image

  • 第六步 :编写添加文章的 views视图
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/views/wiki.py 

...
...
def wiki_add(request, project_id):
    """ wiki 文章添加 """
    if request.method == 'GET':
        form = WikiModelForm(request)
        return render(request, 'wiki_add.html', {'form': form})

    # POST
    form = WikiModelForm(request.POST)

    if form.is_valid():
        form.instance.project = request.bug_manager.project
        form.save()

        # 反向生成url
        url = reverse('wiki', kwargs={'project_id': project_id})
        print(url)
        return redirect(url)
    return render(request, 'wiki_add.html', {'form': form})

image

  • 第七步骤 :wiki model中增加 del __str__(self) 方法,将模型类以字符串的方式输出
class Wiki(models.Model):
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    title = models.CharField(verbose_name='标题', max_length=32)
    content = models.TextField(verbose_name='内容', null=True)

    # 子关联
    # 子关联父文章ID (可以写此表名称或者self,都表示子关联)
    # 反向关联字段 related_name 表示反向查找使用的字段名称
    parent = models.ForeignKey(verbose_name='父文章', to="Wiki", null=True, blank=True, related_name='children',on_delete=models.CASCADE)

    def __str__(self):
        return self.title

image

3.2、修复父文章Bug(父文章,应该仅展示本项目的文章)

  • Form
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/forms/wiki.py 


from django import forms
from web_app.forms.bootstrap import BootStrapForm
from web_app import models

class WikiModelForm(BootStrapForm, forms.ModelForm):

    #  model 定义元数据
    class Meta:
        # 对应的Model类
        model = models.Wiki
        # Model类中哪些字段可以展示,__all__ 表示所有
        # fields = '__all__' 也表示默认的展示顺序,可以手动指定展示顺序
        # exclude 排除哪些字段不展示
        exclude = ['project',]   # 表示项目不进行展示

    # 重写__init__ 仅为在views视图调用Form初始化函数式多传递request参数
    def __init__(self, request, *args, **kwargs):
        super(WikiModelForm, self).__init__(*args, **kwargs)
        self.request = request

        # 找到想要的字段把他绑定显示的数据重置
        # 数据 = 去数据库中获取 当前项目所有的wiki标题
        # self.fields['parent'].choices = [(1,'111'), (2, '222')]
        total_data_list = [("", "请选择"), ]
        data_list = models.Wiki.objects.filter(project=request.bug_manager.project).values_list('id', 'title')  # values_list 返回元祖
        total_data_list.extend(data_list)

        self.fields['parent'].choices = total_data_list

  • views
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/views/wiki.py 


from django.shortcuts import render,redirect,reverse
from web_app.forms.wiki import WikiModelForm

def wiki(request, project_id):
    """ wiki首页 """

    return render(request, 'wiki.html')

def wiki_add(request, project_id):
    """ wiki 文章添加 """
    print(request.method)
    if request.method == 'GET':
        form = WikiModelForm(request)
        return render(request, 'wiki_add.html', {'form': form})

    # POST
    form = WikiModelForm(request, data=request.POST)
    if form.is_valid():
        form.instance.project = request.bug_manager.project
        form.save()

        # 反向生成url
        url = reverse('wiki', kwargs={'project_id': project_id})
        return redirect(url)
    return render(request, 'wiki_add.html', {'form': form})
  • 项目一

image

  • 项目二 :看不到项目一的文章

image

四、wiki文章多级目录展示

4.1、实现方案

4.1.1、方式一 :模板渲染

模板渲染:
	- 数据库中获取的数据要有层级的划分
		queryset = model.Wiki.object.filter(project_id=2)
		将数据构造
		[
			{
				id:1,
				title:'文章1'
				children:[
					{
						id:xxx,
						name:'xxx'
					}
				]
			}
		]
	- 页面显示,循环显示(不知道有多少层)
		递归
		
缺点:
	- 写代码费劲
	- 效率低

4.1.2、方式二 :后端 + 前端完成ajax+ID选择器

后端 + 前端完成ajax+ID选择器
	- 前端:打开页面之后,发送ajax请求获取所有的文档标题信息。
	- 后台:获取所有的文章信息
		queryset = model.Wiki.object.filter(project_id=2).values_list('id','title','parent_id')
		[
			{'id':1, title:'文章1',parent_id:None},
			{'id':2, title:'文章2',parent_id:None},
			{'id':3, title:'文章3',parent_id:None},
			{'id':4, title:'文章4',parent_id:3},
			{'id':5, title:'文章5',parent_id:1},
		]

		直接返回给前端的ajax
	- ajax的回调函数success中获取到 res.data,并循环
		$.each(res.data,function(index,item){
			if(item.parent_id){
				
			}else{
				
			}
		
		})
		
<ul>
	<li id="1">文章1
		<ul>
			<li id='5'>文章5</li>
		</ul>
	</li>
	<li id="2">文章2</li>
	<li id="3">文章3
		<ul>
			<li id='4'>子文章4</li>
		</ul>
	</li>
<ul>

4.2、后端 + 前端完成ajax+ID选择器实现多级目录

  • 第一步 :URL 设计获取目录的路由
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/urls.py       

    url(r'^manage/(?P<project_id>\d+)/', include([
        url(r'^dashboard/$', manage.dashboard, name='dashboard'),
        url(r'^file/$', manage.file, name='file'),
        url(r'^setting/$', manage.setting, name='setting'),
        url(r'^issues/$', manage.issues, name='issues'),
        url(r'^statistics/$', manage.statistics, name='statistics'),

        # url(r'^dashboard/issues/chart/$', manage.issues_chart, name='issues_chart'),
        #
        url(r'^wiki/$', wiki.wiki, name='wiki'),
        url(r'^wiki/add/$', wiki.wiki_add, name='wiki_add'),
        url(r'^wiki/catalog/$', wiki.wiki_catalog, name='wiki_catalog'),	# 获取目录
    ], None)),

    # None 表示 反向代理的 namesapce,如果指定namesapce,前端请求此路由时就需要以{{% namespace_name:name%}} -> {{% haha:statistics_project_user%}}

]
  • 第二步 :Views视图
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/views/wiki.py 

...
...

def wiki_catalog(request, project_id):
    """ wiki 目录查询 """
    """ 仅查询当前项目的目录 """

    # data = models.Wiki.objects.all().values_list("id", "title")
    # data => 获取的是 QuerySet类型的数据,而JsonResponse内部会调用json.dumps(),
        # 当JsonResponse序列化QuerySet类型的数据时就会抛出 :TypeError :Object of type 'QuerySet' is not Json serialicable
    data = models.Wiki.objects.filter(project=request.bug_manager.project).values_list("id", "title", "parent_id")
    # return JsonResponse({"status": True, "data": data})


    # values_list :返回列表(array) => item=[1,"文章1", null]、[2,"文章2",null]
    # data_list = models.Wiki.objects.filter(project=request.bug_manager.project).values_list('id', 'title')

    # values :返回字典 => item={id:1,title:"文章1", parent_id:null}、{id:2,title:"文章2",parent_id:null}
    data = models.Wiki.objects.filter(project=request.bug_manager.project).values('id', 'title')

    return JsonResponse({"status": True, "data": list(data)})
  • 第三步 :Template模板编写ajax请求
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/templates/wiki.html 


{% extends 'layout/manage.html' %}

{% block css %}
    <style>
        .panel-default {
            margin-top: 10px;
        }

        .panel-default .panel-heading {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
        }

        .panel-body {
            padding: 0;
        }

        .title-list {
            border-right: 1px solid #dddddd;
            min-height: 500px;
        }

        .content {
            border-left: 1px solid #dddddd;
            min-height: 600px;
            margin-left: -1px;
        }

    </style>
{% endblock %}

{% block content %}
    <div class="container-fluid">

        <div class="panel panel-default">
            <div class="panel-heading">
                <div>
                    <i class="fa fa-book" aria-hidden="true"></i> wiki文档
                </div>
                <div class="function">
                    <a type="button" class="btn btn-success btn-xs"
                       href="{% url 'wiki_add' project_id=request.bug_manager.project.id %}">
                        <i class="fa fa-plus-circle" aria-hidden="true"></i> 新建
                    </a>

                </div>
            </div>


            <div class="panel-body">
                <div class="col-sm-3 title-list">
                    <ul id="catalog"></ul>
                </div>

                <div class="col-sm-9 content">
                    <div style="text-align: center;margin-top: 50px;">
                        <h4> 《{{ request.bug_manager.project.name }}》wiki文档库 </h4>
                        <a href="{% url 'wiki_add' project_id=request.bug_manager.project.id %}">
                            <i class="fa fa-plus-circle" aria-hidden="true"></i> 新建文章
                        </a>
                    </div>
                </div>
                <div></div>
        </div>
        </div>
    </div>

{% endblock %}

{% block js %}
    <script>
        $(function (){
            initCatalog();
        });

        function initCatalog(){
            $.ajax({
                url: "{% url 'wiki_catalog' project_id=request.bug_manager.project.id %}",
                type: "GET",
                dataType: "JSON",
                success: function (res) {
                    if (res.status) {
                        $.each(res.data, function (index, item) {
                            {#item.id#}
                            {#item.title#}
                            {#item.parent_id#}
                            // 一级标题
                            var li = $("<li>").attr('id', "id_" + item.id).append($('<a>').text(item.title)).append($('<ul>'));
                            if (!item.parent_id) {
                                // 添加到catalog中
                                {#var li = $("<li>").attr('id', "id_" + item.id).append($('<a>').text(item.title)).append($('<ul>'));#}
                                $('#catalog').append(li);
                            // 多级标题
                            } else {
                                {#var li = $("<li>").attr('id', "id_" + item.id).append($('<a>').text(item.title)).append($('<ul>'));#}
                                $("#id_" + item.parent_id).children('ul').append(li);
                            }
                        })
                    } else {
                        alert("初始化目录失败");
                    }
                }
            })
        }
    </script>
{% endblock %}

image

4.3、修复多级目录展示部分存在的问题

4.3.1、问题一 :父目录要提前出现 :排序 + 字段(深度 depth)

ID 标题 内容 项目ID 父ID 深度
1 xx 你好呀 1 深度null 1
2 haha ffff 1 null
3 hehe fsd 1 1
  • 第一步 :models 增加字段(深度 depth


class Wiki(models.Model):
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    title = models.CharField(verbose_name='标题', max_length=32)
    content = models.TextField(verbose_name='内容', null=True)

    depth = models.IntegerField(verbose_name="深度", default=1)

    # 子关联
    # 子关联父文章ID (可以写此表名称或者self,都表示子关联)
    # 反向关联字段 related_name 表示反向查找使用的字段名称
    parent = models.ForeignKey(verbose_name='父文章', to="Wiki", null=True, blank=True, related_name='children',on_delete=models.CASCADE)

    def __str__(self):
        return self.title
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % python3 manage.py makemigrations
Migrations for 'web_app':
  web_app/migrations/0006_wiki_depth.py
    - Add field depth to wiki
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % python3 manage.py migrate       
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, users_app, web_app
Running migrations:
  Applying web_app.0006_wiki_depth... OK
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % 

image

  • 第二步 :Views 优化目录查询视图,使用根据深度排序
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/views/wiki.py 

...
...
def wiki_catalog(request, project_id):
    """ wiki 目录查询 """
    """ 仅查询当前项目的目录 """

    # data = models.Wiki.objects.all().values_list("id", "title")
    # data => 获取的是 QuerySet类型的数据,而JsonResponse内部会调用json.dumps(),
        # 当JsonResponse序列化QuerySet类型的数据时就会抛出 :TypeError :Object of type 'QuerySet' is not Json serialicable
    # data = models.Wiki.objects.filter(project=request.bug_manager.project).values_list("id", "title", "parent_id")
    # return JsonResponse({"status": True, "data": data})


    # values_list :返回列表(array) => item=[1,"文章1", null]、[2,"文章2",null]
    # data_list = models.Wiki.objects.filter(project=request.bug_manager.project).values_list('id', 'title')

    # values :返回字典 => item={id:1,title:"文章1", parent_id:null}、{id:2,title:"文章2",parent_id:null}
    # data = models.Wiki.objects.filter(project=request.bug_manager.project).values('id', 'title')
    data = models.Wiki.objects.filter(project=request.bug_manager.project).values('id', 'title').order_by('depth', 'id')
    return JsonResponse({"status": True, "data": list(data)})
  • 第三步 :Views 优化文章添加视图,判断用户是否选择了父文章
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/views/wiki.py 
...
...
def wiki_add(request, project_id):
    """ wiki 文章添加 """
    print(request.method)
    if request.method == 'GET':
        form = WikiModelForm(request)
        return render(request, 'wiki_add.html', {'form': form})

    # POST
    form = WikiModelForm(request, data=request.POST)
    if form.is_valid():

        # 判断用户是否已经选择父文章
        # print(form.instance.parent, type(form.instance.parent))
        if form.instance.parent:
            form.instance.depth = form.instance.parent.depth + 1
        else:
            form.instance.depth = 1

        form.instance.project = request.bug_manager.project
        form.save()
...
...
  • 第四步 :Form 中表单也不需要展示 depth深度字段
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/forms/wiki.py 

from django import forms
from web_app.forms.bootstrap import BootStrapForm
from web_app import models

class WikiModelForm(BootStrapForm, forms.ModelForm):

    #  model 定义元数据
    class Meta:
        # 对应的Model类
        model = models.Wiki
        # Model类中哪些字段可以展示,__all__ 表示所有
        # fields = '__all__' 也表示默认的展示顺序,可以手动指定展示顺序
        # exclude 排除哪些字段不展示
        exclude = ['project','depth']   # 表示项目不进行展示

    # 重写__init__ 仅为在views视图调用Form初始化函数式多传递request参数
    def __init__(self, request, *args, **kwargs):
        super(WikiModelForm, self).__init__(*args, **kwargs)
        self.request = request

        # 找到想要的字段把他绑定显示的数据重置
        # 数据 = 去数据库中获取 当前项目所有的wiki标题
        # self.fields['parent'].choices = [(1,'111'), (2, '222')]
        total_data_list = [("", "请选择"), ]
        data_list = models.Wiki.objects.filter(project=request.bug_manager.project).values_list('id', 'title')  # values_list 返回元祖
        total_data_list.extend(data_list)

        self.fields['parent'].choices = total_data_list

4.3.2、问题二 :点击文章链接,显示文章详细

4.3.2.1、实现思路梳理

  • Urls
        url(r'^wiki/detail/$', wiki.wiki_detail, name='wiki_detail'),
  • views
def wiki_detail(request, project_id, wiki_id):
    """ 文章详细页面 
        /detail?wiki_id=1
        /detail?wiki_id=2
    """
    return JsonResponse("查看文章详细页面")
  • Templates
{% block js %}
    <script>

        // http://127.0.0.1:8002/manage/2/wiki/detail/
        var WIKI_DETAIL_URL = "{% url 'wiki_detail' project_id=request.bug_manager.project.id %}";

        $(function () {
            initCatalog();
        });

        function initCatalog() {
            $.ajax({
                url: "{% url 'wiki_catalog' project_id=request.bug_manager.project.id %}",
                type: "GET",
                dataType: "JSON",
                success: function (res) {
                    if (res.status) {
                        $.each(res.data, function (index, item) {
                            var href = WIKI_DETAIL_URL + "?wiki_id=" + item.id;
                            var li = $("<li>").attr('id', "id_" + item.id).append($('<a>').text(item.title).attr('href', href)).append($('<ul>'));

                            if (!item.parent_id) {
                                // 添加到catalog中
                                $('#catalog').append(li);
                            } else {
                                $("#id_" + item.parent_id).children('ul').append(li);
                            }
                        })
                    } else {
                        alert("初始化目录失败");
                    }
                }
            })
        }
    </script>
{% endblock %}

image

4.3.2.2、实现点击文章目录查看详情

  • 视图函数使用 wiki首页

    • 如果请求有 wiki_id=1 ,则表示请求查看文章详细
    • 否则表示请求文章 wiki首页
  • 第一步 :完善 views ,wiki首页

(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/views/wiki.py 

from django.shortcuts import render,redirect,reverse
from django.http import JsonResponse
from web_app.forms.wiki import WikiModelForm
from web_app import models

def wiki(request, project_id):
    """ wiki首页 """
    wiki_id = request.GET.get('wiki_id')
    if not wiki_id or not wiki_id.isdecimal():  # 判断是否存在或是十进制小数
        return render(request, 'wiki.html')

    wiki_object = models.Wiki.objects.filter(id=wiki_id, project_id=project_id).first()
    return render(request, 'wiki.html', {'wiki_object': wiki_object})
...
...
  • 第二步 :Template模板获取文章详情切换成反向代理 wiki
(Bug_manager) daizhe@daizhedeMacBook-Pro Bug_manager % cat web_app/templates/wiki.html 


{% block js %}
    <script>

        // http://127.0.0.1:8002/manage/2/wiki/detail/
        var WIKI_DETAIL_URL = "{% url 'wiki' project_id=request.bug_manager.project.id %}";

        $(function () {
            initCatalog();
        });

        function initCatalog() {
            $.ajax({
                url: "{% url 'wiki_catalog' project_id=request.bug_manager.project.id %}",
                type: "GET",
                dataType: "JSON",
                success: function (res) {
                    if (res.status) {
                        $.each(res.data, function (index, item) {
                            var href = WIKI_DETAIL_URL + "?wiki_id=" + item.id;
                            var li = $("<li>").attr('id', "id_" + item.id).append($('<a>').text(item.title).attr('href', href)).append($('<ul>'));

                            if (!item.parent_id) {
                                // 添加到catalog中
                                $('#catalog').append(li);
                            } else {
                                $("#id_" + item.parent_id).children('ul').append(li);
                            }
                        })
                    } else {
                        alert("初始化目录失败");
                    }
                }
            })
        }
    </script>
{% endblock %}

posted @ 2021-07-31 20:15  SRE运维充电站  阅读(1029)  评论(0编辑  收藏  举报