文章目录

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

今日内容

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


一、效果展示

  • 登录首页展示

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

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

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

二、代码展示

1.从主页进入后台

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

<!--主页index.html导航条-->
<ul class="nav navbar-nav navbar-right">{% if request.tracer %}<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ request.tracer.username }}<span class="caret"></span></a><ul class="dropdown-menu"><!--如果已经登录,会显示后台管理,点击即可进入--><li><a href="{% url 'app01:project_list' %}">后台管理</a></li><li role="separator" class="divider"></li><li><a href="{% url 'app01:logout' %}">退出</a></li></ul></li><!--否则只会显示注册和登录按钮-->{% else %}<li><a href="{% url 'app01:register' %}">注册</a></li><li><a href="{% url 'app01:login' %}">登录</a></li>{% endif %}
</ul>

上一节已经说过,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:continuefield.widget.attrs["class"] = "form-control field"field.widget.attrs["placeholder"] = '请输入'+field.labelfield.error_messages['required'] = '此字段必须填写'# app01/forms/project.py
class ProjectForm(BootstrapForm, forms.ModelForm):class Meta:model = models.Projectfields = ['name', 'color', 'desc']

2.3 前端模板

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

<!--主页index.html导航条-->
<nav class="navbar navbar-inverse"><div class="container-fluid"><!-- Brand and toggle get grouped for better mobile display --><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand active" href="{% url 'app01:project_list' %}">Tracer</a></div><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><ul class="nav navbar-nav navbar-right"><li><a href="#">工作台</a></li><li><a href="#">日历</a></li><li><a href="#"><span class="glyphicon glyphicon-bell" aria-hidden="true"></span></i></a></li><li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ request.tracer.username }}<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="{% url 'app01:index' %}">官网</a></li><li role="separator" class="divider"></li><li><a href="{% url 'app01:logout' %}">退出</a></li></ul></li></ul></div></div>
</nav>

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

后台主页面继承基模板,再用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 新建按钮和模态框

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

<div class="add"><a class="btn btn-primary" href="javascript:" data-toggle="modal" data-target="#myModal" id="canCreate"><i class="fa fa-plus" aria-hidden="true"></i> 新建项目</a>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<!--内容太多了,访问https://v3.bootcss.com/javascript/#modals查看模态框详细样式-->
</div>

这样就写完了之后,模态框的表单中使用{{ 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_nameoption_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" %}<!--multiple_input.html-->
{% set id = widget.attrs.id %}<ul{% if id %} id="{{ id }}"{% endif %} {% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>
{% for group, options, index in widget.optgroups %}{% if group %}<li>{{ group }}<ul{% if id %} id="{{ id }}_{{ index }}"{% endif %}>{% endif %}{% for widget in options %}<li>{% include widget.template_name %}</li>{% endfor %}{% if group %}</ul></li>{% endif %}{% endfor %}
</ul>

自定义的radio.html

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

源码中的radio_option.html

{% include "django/forms/widgets/input_option.html" %}<!--input_option.html-->
{% if widget.wrap_label %}<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %}>
{% endif %}
{% include "django/forms/widgets/input.html" %}
{% if widget.wrap_label %} {{ widget.label }}</label>{% endif %}

自定义的color_option.html

{% include "app01/widgets/input_option.html" %}<!--input_option.html-->
{% if widget.wrap_label %}
<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}" class="color-select"{% endif %}>
{% endif %}
{% include "django/forms/widgets/input.html" %}
<span class="cycle" style="display:inline-block; width:40px; height: 40px; border-radius: 20px;background-color:{{widget.label}}"></span>
</label>

3.3 添加项目后台校验

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

# 视图函数
# app01/views/project.py
def project_list(request):# ...if form.is_valid():form.instance.creator = request.tracerform.save()return JsonResponse({"status": 1})return JsonResponse({"status": 0, "msg": form.errors})
// 前端代码
function bindSubmitEvent(){$("#create_project").click(function () {$.ajax({url: "{% 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.pydef 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.pydef 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 %}<!-- ... --><!--星标的图标,点击即可取消星标,传入项目来源(我创建的还是我参与的)和项目id--><a href="{% url 'app01:cancel_star' item.project_type item.project.id %}" style="color:#ffd700;"><span class="glyphicon glyphicon-star star"></span></a>{% endfor %}

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

# app01/views/project.pydef 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}
  • 编写模板
<!--app01/templates/inclusion/all_projects.html--><ul class="dropdown-menu">{% if my %}<li><a href="javascript:"><b><i class="fa-brands fa-angellist"></i> 我创建的项目</b></a></li>{% for item in my %}<li><a href="#">{{ item.name }}</a></li>{% endfor %}{% endif %}{% if join %}<li role="separator" class="divider"></li><li><a href="javascript:"><b><i class="fa-regular fa-hand"></i> 我参与的项目</b></a></li>{% for item in join %}<li><a href="#">{{ item.name }}</a></li>{% endfor %}{% endif %}<li role="separator" class="divider"></li><li><a href="{% url 'app01:project_list' %}"><b><span class="glyphicon glyphicon-list"></span> 所有项目</b></a></li>
</ul>
  • 最后在基模板中引入即可

三、总结

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

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

  1. Django simpleui实战web平台开发

    先上效果图: 本次使用Django simple ui 进行了简易的界面,使用h5的基本功能,比传统的qt和tk更加方便使用,界面更加符合审美.通过Django的框架实现简易的web平台开发. 代码分 ...

  2. 基于 OpenFire 的TVBox管理平台开发笔记

    目录 一.開發環境設置.... 3 1.1 JDK 安裝.... 3 1.2 MySql Server安裝.... 4 1.3 OpenFire安裝.... 6 1.4 Openfire Admin ...

  3. 厨卫电器行业B2B交易协同管理平台开发,优化企业库存结构

    后疫情时代,我国厨卫电器行业除集成灶.洗碗机等部分新兴产品外,市场整体呈现低迷状态.这样的状态一方面是由于疫情影响造成的市场扰动,但最根本的还是厨卫电器行业进入到了存量市场,市场竞争愈加激烈,企业稍有 ...

  4. 基于 Vue 的学生社团线上管理平台开发与设计

    0 引言 近年来, 各高校为丰富学生的校园生活. 培养学生的个性, 社团与社团人数增加迅速, 需要处理的各类信息也层出不穷, 传统的管理方式已经不利于快捷地处理这些问题. 因此管理不便. 信息错综复杂 ...

  5. 书写一个管理平台开发常用的通用table组件

    来现在这公司一年了,一年时间里经手做的项目有六七个,不过呢大部分都是一些管理平台的功能,而管理平台做的最多的就是各种表格的展示了,所以在开发过程中,为了提高开发效率,封装一些通用的功能组件是十分有必要 ...

  6. 物联网开发智慧城镇管理平台开发

    智慧城镇综合管理平台面向政府机关部门. 过登录后台界面,可以宏观调控各种资源;合理安排各部门分工合作. 在各种紧急事件发生时,可以快速反应,精准定位并作出相应对策,大幅度降低人员伤亡和财产损失. 将互 ...

  7. 新闻舆情管理平台开发,监控舆情发展趋势

    打造企业良好声誉可能需要几年.十几年甚至更久,而毁掉它只需要短短几分钟.尤其是互联网时代下,人们接收信息的速度越来越快,在新闻发出去的几分钟内就能迅速占据热搜榜.而且网络上每天都会产生上亿条信息,单纯 ...

  8. 搭建企业级微信公众号管理平台(二)----WxJava框架快速开发微信公众号

    1.WxJava  微信公众号框架初体验 WxJava  微信公众号框架  https://github.com/Wechat-Group/WxJava //下载xwjava全量的SDK代码 git ...

  9. php应用开发综合课程设计,学生综合测评管理平台开发(PHP)

    摘要:当前我国普通高校综合测评管理方式大多还停留在纸质的基础上, 已经不能适应信息时代的发展.文章结合当前高校的实际情况, 利用PHP语言和My SQL数据库构建一套符合综合测评要求的信息化系统. 关 ...

最新文章

  1. Qtum量子链受邀出席日本早稻田研究所区块链教育讲座
  2. Docker中运行Springboot jar时的变量传递
  3. .Netcore 2.0 Ocelot Api网关教程(6)- 配置管理
  4. 打印两个有序链表的公共部分~~
  5. 【Jmeter篇】Jmeter踩坑记(一)
  6. Spring框架 DI
  7. linux raw格式改名img,4款Linux下的RAW格式图片编辑软件
  8. 互联网运营数据分析(1):流量分析
  9. Win32 SDK创建ListView控件
  10. 创建 macvlan 网络 - 每天5分钟玩转 Docker 容器技术(55)
  11. 学计算机编程有什么用,编程是什么 学习编程的好处
  12. R大 关于 G1 算法原理的解释说明
  13. Java程序怎么运行?
  14. 盗版windows xp摇身一变成正版(不用算号器)
  15. 非凡的键盘钢琴音源 XLN Audio Addictive Keys Complete 1.1.8 WiN-MAC
  16. 各国程序员薪资水平,看完我想静静。。。
  17. 有哪些文艺而有韵味的句子?
  18. P800 GPS 地图安装教程
  19. 生活在同一片土地上,印度人肤色差异为何那么大?
  20. 视觉问答06day[综述]:一文带你了解视觉问答VQA

热门文章

  1. L1-020 帅到没朋友 (20分)
  2. IDEA中JSP乱码问题解谜
  3. 036 《你喜欢的样子我都有》观后感
  4. PHPExcel读取excel数据
  5. 解析:微软收购诺基亚硬件或为Asha
  6. AD PCB实用常用快捷键总结
  7. C语言中if和switch语句的基本用法
  8. 安全测试演练环境搭建
  9. MySQL主从复制安装配置
  10. 吉利集团发展史成本演化(一天的成果)