wiki文档库功能实现

  • 建模
class Wiki(models.Model):
    title = models.CharField(max_length=32,verbose_name='标题')
    content = models.TextField(verbose_name='内容')
    project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='项目名称')
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='parents', verbose_name='父文档')
    depth = models.SmallIntegerField(default=1,verbose_name='深度')

    def __str__(self):
        return self.title
  • 当前端页面加载完成的时候,就向后端发起ajax请求,获取所有目录标题
    所以,必须有一个接口来返回这些内容
# urls
url(r'^single_manage/(?P<project_id>\d+)/', include([
        ......
        url(r'^wiki/catalog$', wiki.wiki_catalog, name='wiki_catalog'),
    ])),,

# views

'''
- 获取字段: id,title,parent_id

- 还需排序:

    - 先按照 depth 排序:即先渲染所有一级目录

    - 然后按照 id 排序:最先添加的文章就拍在前面
'''


def wiki_catalog(request,project_id):
    data = Wiki.objects.filter(project=request.project).values('id','title','parent_id').order_by('depth','id')
    return JsonResponse({
        'status':True,
        'data':list(data)
    })
  • 前端部分,页面一旦加载完毕,立马向后端发送请求,获取所有的目录标题
    先渲染一级目录,然后在此基础上,一直向后面渲染
# html模板
......
 <div class="panel-body">
    <div class="col-sm-3 title-list">
        <ul id="catalog">
            <!--js渲染待插入的内容-->
        </ul>
    </div>
......
{% block custom_js %}
    <script>

        // 页面加载的时候,立即执行
        $(function(){
            initCatalog();
        })

        function initCatalog(){
            $.ajax({
                url:'{% url "wiki_catalog"  project_id=request.project.id %}',
                type:'GET',
                dataType:'JSON',
                success: function(res){
                   if (res.status){
                        // 遍历每一项
                        $.each(res.data,function(index,item){
                            // <li id="id_num"><a href="#">字段标题内容<ul>......
                            var li = $('<li>').attr('id',"id_" + item.id).append($('<a>').text(item.title).attr('href','#')).append($('<ul>'));
                            // 优先渲染一级目录,有了一级目录,才有以后的二,三...级目录
                            if(!item.parent_id){
                                $('#catalog').append(li);
                            }else{ // 如果不是一级目录,就在原有目录的基础上,再添加进去
                                $('#id_' + item.parent_id).children('ul').append(li);
                            }
                        })
                   }else{
                       alert('初始化目录失败!')
                   }
                }
            })
        }

    </script>
{% endblock %}

wiki 的增加功能演示

# url
url(r'^single_manage/(?P<project_id>\d+)/', include([ 
        ......
        url(r'^wiki/add$', wiki.wiki_add, name='wiki_add'),
        ......
    ])),

# views
'''
    - get: 加载页面

    - post: 获取 project 对象,存入db
'''
def wiki_add(request,project_id):
    if request.method == 'GET':
        form = WikiModelForm(request)
        context = {
            'form':form
        }
        return render(request,'wiki_add.html',context=context)
    
    form = WikiModelForm(request,data=request.POST)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.project = request.project
        instance.save()
        return redirect(reverse('wiki',kwargs={'project_id':project_id}))
    return render(request, 'wiki.html', {'error':form.errors})

# forms
'''
    - colorRadioSelect做的事情是,只修改前端样式,数据源不变
    
    - 本次要做的是,数据源变,但样式不变:
    
        - 把数据源'所有文档'变成'本项目的文档'
'''
class WikiModelForm(BootStrapForm, forms.ModelForm):

    class Meta:
        model = Wiki
        exclude = ['project','depth']

    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        # 测试数据: self.fields['parent'].choices=[(1,'xxx'),(2,'yyy')]
        data_list = [('','请选择')]
        query_set = Wiki.objects.filter(project=request.project).values_list('id','title')
        data_list.extend(query_set)
        self.fields['parent'].choices=data_list
  • 前端使用传统的表单提交方式
<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 %}
      <input type="submit" class="btn btn-primary" value="提交"/>
    </form>
</div>