栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django轻量级任务追踪管理平台开发:二

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django轻量级任务追踪管理平台开发:二

文章目录
  • 今日内容
  • 一、效果展示
  • 二、代码展示
    • 1.从主页进入后台
    • 2.后台页面
      • 2.1 后台界面路由
      • 2.2 后台视图函数
      • 2.3 前端模板
    • 3.新建项目
      • 3.1 表设计
      • 3.2 新建按钮和模态框
      • 3.3 添加项目后台校验
      • 3.4 星标和取消星标
      • 4. 补充
  • 三、总结


今日内容

前一篇文章介绍了项目的认证,主要是注册和登录,今天介绍后台管理和项目创建


一、效果展示
  • 登录首页展示

    其实这是一个静态页面和一个图片(图片要是自己生成确实NB,然而本菜鸟不会),导航栏中只有右边用户名的位置可以点,点击后台管理就可以进入后台管理主页了。
  • 后台管理主页

    点击新建项目会弹出模态框,然后就可以创建项目了。点击星星图标可以进行星标。

以上就是今天主要内容,接下来是代码展示。

二、代码展示 1.从主页进入后台

第一步是在登录成功之后,通过选择右上角下拉框进入后台管理页面



上一节已经说过,request.tracer是通过中间件进行判断后,保存起来的用户信息。

2.后台页面 2.1 后台界面路由
path('project/list/', project.project_list, name='project_list'),
2.2 后台视图函数
def project_list(request):
    if request.method == 'GET':
        form = ProjectForm(request)
        return render(request, 'app01/project_list.html', {'form': form})

不错,这里使用ModelForm将数据库中的数据传入后端直接渲染

# app01/forms/bootstrap.py
# 用于封装bootstrap的一些样式:
	# 字段使用form-control
	# 添加placeholder属性
	# 'required'错误提示
class BootstrapForm:
	# 不使用此样式的字段
    bootstrap_exclude = []
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            if field_name in self.bootstrap_exclude:
                continue
            field.widget.attrs["class"] = "form-control field"
            field.widget.attrs["placeholder"] = '请输入'+field.label
            field.error_messages['required'] = '此字段必须填写'


# app01/forms/project.py
class ProjectForm(BootstrapForm, forms.ModelForm):
    class Meta:
        model = models.Project
        fields = ['name', 'color', 'desc']
2.3 前端模板

由于后台所有页面都要用到同样的导航条,因此先写一个基模板。这里使用了bootstrap中的navbar。



基本效果如下(不包括 <项目>那里的代码):

后台主页面继承基模板,再用bootstrap的panel组建展示项目即可。但是目前还没有项目,咱还没有新建呢。

3.新建项目 3.1 表设计
# models.py
class Project(models.Model):
    """创建的项目"""
    color_choices = (
        (1, "#fa5151"),
        (2, "#c87d2f"),
        (3, "#91d300"),
        (4, "#10aeff"),
        (5, "#6467f0"),
        (6, "#07c160")
    )
    name = models.CharField(verbose_name='项目名', max_length=32)
    color = models.SmallIntegerField(verbose_name='颜色', choices=color_choices, default=3)
    desc = models.CharField(verbose_name='项目描述', max_length=255, null=True, blank=True)
    use_space = models.IntegerField(verbose_name='项目已用空间', default=0)
    star = models.BooleanField(verbose_name='星标', default=False)

    join_count = models.SmallIntegerField(verbose_name='参与人数', default=1)
    creator = models.ForeignKey(verbose_name='创建者', to='UserInfo', on_delete=models.CASCADE)
    create_datetime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
3.2 新建按钮和模态框

创建一个按钮,点击弹出模态框,展示一个表单即可。



这样就写完了之后,模态框的表单中使用{{ field }}就可以列举出所有的字段。

这里比较难的是颜色字段如何如图展示。正常情况下应该是普通的RadioSelect样式,要想改变样式,需要自己写一个类,继承RadioSelect。
先看一下RadioSelect的源码

class RadioSelect(ChoiceWidget):
    input_type = 'radio'
    template_name = 'django/forms/widgets/radio.html'
    option_template_name = 'django/forms/widgets/radio_option.html'

自定义的时候只要重写template_name 和option_template_name 就可以了。

# app01/forms/project.py
class ColorSelect(RadioSelect):
    input_type = 'radio'
    template_name = 'app01/widgets/radio.html'
    option_template_name = 'app01/widgets/color_option.html'

源码中radio.html

{% include "django/forms/widgets/multiple_input.html" %}


{% set id = widget.attrs.id %}


{% for group, options, index in widget.optgroups %}
	{% if group %}
 			
  • {{ group }} {% endif %} {% for widget in options %}
  • {% include widget.template_name %}
  • {% endfor %} {% if group %} {% endif %} {% endfor %}

    自定义的radio.html

    {% include "app01/widgets/multiple_input.html" %}
    
    
    {% with id=widget.attrs.id %}
    
    { id }}"{% endif %}{% if widget.attrs.class %} {% endif %}>    
        {% for group, options, index in widget.optgroups %}
            {% for option in options %}
                
    {% include option.template_name with widget=option %}
    {% endfor %} {% endfor %}
    {% endwith %}

    源码中的radio_option.html

    {% include "django/forms/widgets/input_option.html" %}
    
    
    {% if widget.wrap_label %}
    	
    {% endif %}
    {% include "django/forms/widgets/input.html" %}
    {% if widget.wrap_label %} {{ widget.label }}{% endif %}
    

    自定义的color_option.html

    {% include "app01/widgets/input_option.html" %}
    
    
    {% if widget.wrap_label %}
    
    {% endif %}
    {% include "django/forms/widgets/input.html" %}
    {widget.label}}">
    
    
    3.3 添加项目后台校验

    模态框发送ajax请求,后台将通过ModelForm进行校验之后,写入数据库,同时返回数据给前端

    # 视图函数
    # app01/views/project.py
    def project_list(request):
    	# ...
        if form.is_valid():
            form.instance.creator = request.tracer
            form.save()
            return JsonResponse({"status": 1})
        return JsonResponse({"status": 0, "msg": form.errors})
    
    // 前端代码
    function bindSubmitEvent(){
        $("#create_project").click(function () {
            $.ajax({
                url: "https://blog.csdn.net/qq_45829545/article/details/{% url 'app01:project_list' %}",
                type: 'post',
                dataType: 'json',
                data: $("#projectForm").serialize(),
                success: function (ret) {
                    console.log(ret);
                    if (ret.status===0){
                    	// 发送,模态框显示错误信息
                        $.each(ret.msg, function (key, value) {
                            $("#id_"+key).next().html(value);
                        })
                    }else{
                    	// 成功,直接刷新
                        location.reload();
                    }
                }
            })
        })
    }
    

    由此,添加项目功能已经实现。现在在展示后台首页时,可以在每次GET请求时获取所有项目,展示出来。

    # app01/views/project.py
    
    def project_list(request):
        if request.method == 'GET':
            form = ProjectForm(request)
            # 存放所有项目用于前端显示
            project_display = {"join": [], "create": []}
            # 我创建的
            all_projects = models.Project.objects.filter(creator=request.tracer)
            for project in all_projects:
                project_display['create'].append(project)
            # 我参与的
            join_projects = models.ProjectUser.objects.filter(user=request.tracer)
            for project in join_projects:
                project_display['join'].append(project)
            return render(request, 'app01/project_list.html', {'form': form, 'project_display': project_display})
    
    3.4 星标和取消星标

    星标项目比较简单,只需在图标上添加一个url,将项目id传入,后台将这个项目的star字段设为True即可。主要是要区分是“我创建的”还是“我参与的”,因为这决定了在哪个表中查。

    # app01/views/project.py
    # 前端星标图标,如果在“我创建的项目”中,就传一个“my”,如果在“我参与的项目”中,传一个“join”
    
    def star(request, project_type, project_id):
        if project_type == 'my':
            models.Project.objects.filter(id=project_id, creator=request.tracer).update(star=True)
        elif project_type == 'join':
            models.ProjectUser.objects.filter(project_id=project_id, user=request.tracer).update(star=True)
        return redirect('app01:project_list')
    

    但是取消星标就比较复杂了,这个项目取消星标之后,到底该放到“我创建的项目”中,还是“我参与的项目”中,是个难点。
    为了解决这一点,需要在之前构建project_display时,增加一个字段star,保存当前星标项目的id和来源。

    # app01/views/project.py
    
    def project_list(request):
        if request.method == 'GET':
            form = ProjectForm(request)
            # 存放所有项目用于前端显示
            project_display = {"star": [], "join": [], "create": []}
            # 我创建的
            all_projects = models.Project.objects.filter(creator=request.tracer)
            for project in all_projects:
                if project.star:
                    project_display['star'].append({"project": project, "project_type": "my"})
                else:
                    project_display['create'].append(project)
            # 我参与的
            join_projects = models.ProjectUser.objects.filter(user=request.tracer)
            for project in join_projects:
                if project.start:
                    project_display['star'].append({"project": project, "project_type": "join"})
                else:
                    project_display['join'].append(project)
            return render(request, 'app01/project_list.html', {'form': form, 'project_display': project_display})
    

    这样前端“星标项目”就可以这样写:

    {% for item in project_display.star %}
    	
    	
         
             
         
    
    {% endfor %}
    

    取消星标视图函数,根据不同来源去不同的表里查找然后取消星标就可以了。

    # app01/views/project.py
    
    def cancel_star(request, project_type, project_id):
        if project_type == 'my':
            models.Project.objects.filter(id=project_id, creator=request.tracer).update(star=False)
        elif project_type == 'join':
            models.ProjectUser.objects.filter(project_id=project_id, user=request.tracer).update(star=False)
        return redirect('app01:project_list')
    
    4. 补充

    导航栏有一个“项目”的选项,点击会出现一个下拉框,可以选择当前的项目。

    这个如何显示呢?需要用到inclusion_tag

    • 首先定义一个inclusion_tag
    # app01/templatetags/tags.py
    
    @register.inclusion_tag("app01/inclusion/all_projects.html")
    def fetch_project(request):
        create_project = models.Project.objects.filter(creator=request.tracer)
        join_project = models.ProjectUser.objects.filter(user=request.tracer)
        return {"my": create_project, "join": join_project}
    
    • 编写模板
    
    
    
    
    
    • 最后在基模板中引入即可
    三、总结

    今天聊了一下后台主页的展示,项目的创建,难点是模态框中对于默认RadioSelect的自定义,需要注意的是inclusion_tag的使用和项目取消星标的设计。
    下一步就是进入创建的每一个项目了,内容也会越来越多。当然这个项目不是我自创的,而是学习的别人的,有兴趣的小伙伴可以去看武沛琪老师的讲解!武老师的B站课程

    转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/1029622.html

    Python相关栏目本月热门文章

    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号