轻量级bug管理平台——管理中心

管理中心预计效果如下:

轻量级bug管理平台——管理中心

django写离线脚本

探讨业务

设计表结构

我的表结构

功能实现【任务】

  • 查看项目列表
  • 创建项目
  • 星标项目

今日详细

1、django 离线脚本

  • django ,框架
  • 离线,非web运行时(运行时与django运行与否没有关系)
  • 脚本,一个或者几个py文件
  • 了解以上知识点后在某个py文件中对django项目做一些处理。

web运行时的含义:运行django程序运行起来就叫django运行时,即Web网站运行起来,对于视图文件的视图函数是通过浏览器中访问网站,django网站自动触发函数,函数被称为web在运行时被django调用的函数。

示例1:使用离线脚本在用户表插入数据(仅运行i脚本文件)

仅运行脚本文件时要特地往数据库添加数据:链接数据库、操作、关闭链接#而在django启动时,实际上是执行manage.py文件,在运行是会把所有的配置文件加载在项目中,。这时候就可以链接数据库并运行了,但离线脚本是不行的。在django中写离线脚本的程序如下:在init_user中:
import osimport sysimport djangobase_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 绝对路径,不断地往上一层找,从而找到它的根目录.sys.path.append(base_dir)  # 将根目录写在sys.path下,在内部就导入s25下面的那个settingsos.environ.setdefault("DJANGO_SETTINGS_MODULE",                      "bugmanagment.settings")  # 将bugmanagment.settings写入DJANGO_SETTINGS_MODULE环境变量中django.setup()  # os.environ['DJANGO_SETTINGS_MODULE']  #模拟django的manage.py文件,进行模拟运行django启动,从而读到配置文件from app01 import models# 仅运行脚本文件时:往数据库添加数据:链接数据库、操作、关闭链接models.UserInfo.objects.create(username='陈硕', email='chengshuo@live.com', mobile_phone='13838383838', password='123123')

运行结果如下:(加入数据库里面的结果:

示例2:数据库录入全国省市县

示例3:朋友圈项目敏感字、词语

示例4:saas免费版(为所有人提供项目管理平台)【价格策略通过离线脚本添加进去)

注:大量数据要插入数据库中时可以利用一下django的离线脚本进行操作。

2. 探究业务( 表设计)

轻量级bug管理平台——管理中心

轻量级bug管理平台——管理中心

注:request.tracer = 交易对象

轻量级bug管理平台——管理中心

轻量级bug管理平台——管理中心

轻量级bug管理平台——管理中心

3

1、创建相应表结构:

知识点扩展:

轻量级bug管理平台——管理中心

加入related_name解决一张表关联着同一张表的ForeignKey的问题

轻量级bug管理平台——管理中心
class ProjectUser(models.Model):
    # 项目参与者
    user = models.ForeignKey(verbose_name='参与者', to='UserInfo', related_name='a', on_delete=models.CASCADE)
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    star = models.BooleanField(verbose_name='星标', default=False)
    invitee = models.ForeignKey(verbose_name='邀请者', to='UserInfo', related_name='b', on_delete=models.CASCADE)
    create_datetime = models.DateTimeField(verbose_name='加入时间', auto_now_add=True)

obj = UserInfo.objects.filter(id=1)  # 用户对象

obj.projectuser_set.all()  #通过字段反向关联ProjectUser表,但是因为一张表关联着同一张的ForeignKey,则应该用下一个操作才能实现
obj.a.all()
#或者obj.b.all()

代码:

from django.db import models

class UserInfo(models.Model):
    username = models.CharField(verbose_name='用户名', max_length=32, db_index=True)  # db_index=True 创建索引
    email = models.EmailField(verbose_name='邮箱', max_length=32)
    mobile_phone = models.CharField(verbose_name='手机号', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=32)

    # price_policy = models.ForeignKey(verbose_name="价格策略", to='PricePolicy', null=True, blank=True)

    def __str__(self):
        return self.username

    class Meta:
        db_table = "UserInfo"
        verbose_name_plural = '用户表'

class PricePolicy(models.Model):
    """价格策略"""
    category_choices = (
        (1, '免费版'),
        (2, '收费版'),
        (3, '其他'),
    )
    category = models.SmallIntegerField(verbose_name='收费类型', default=1, choices=category_choices)

    title = models.CharField(verbose_name='标题', max_length=32)
    price = models.PositiveIntegerField(verbose_name='价格')  # 存正整数

    project_num = models.PositiveIntegerField(verbose_name='项目数')
    project_member = models.PositiveIntegerField(verbose_name='项目成员数')
    project_space = models.PositiveIntegerField(verbose_name='单项目空间')
    per_file_size = models.PositiveIntegerField(verbose_name='单文件大小')

    create_datetime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)

class Transaction(models.Model):
    # 交易记录
    status_choice = (
        (1, '未支付'),
        (2, '已支付')
    )
    status = models.SmallIntegerField(verbose_name='状态', choices=status_choice)

    order = models.CharField(verbose_name='订单号', max_length=64, unique=True)  # 唯一索引
    user = models.ForeignKey(verbose_name='用户', to='UserInfo', on_delete=models.CASCADE)

    price_policy = models.ForeignKey(verbose_name='价格策略', to='PricePolicy', on_delete=models.CASCADE)
    count = models.IntegerField(verbose_name='数量(年)', help_text='0表示无限期')
    price = models.IntegerField(verbose_name='实际支付价格')

    start_datetime = models.DateTimeField(verbose_name='开始时间', null=True, blank=True)
    end_datetime = models.DateTimeField(verbose_name='结束时间', null=True, blank=True)  # 为空代表无限期

    create_datetime = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)

class Project(models.Model):
    """项目表"""
    COLOR_CHOICES = (
        (1, "#56b8eb"),
        (2, "#f28033"),
        (3, "#ebc656"),
        (4, "#a2d148"),
        (5, "#20BFA4"),
        (6, "#7461c2"),
        (7, "#20bfa3"),
    )
    name = models.CharField(verbose_name='项目名', max_length=32)
    color = models.SmallIntegerField(verbose_name='颜色', choices=COLOR_CHOICES, default=1)
    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)

    # 查询:可以省事;(根据project_user字段进行查询)
    # 增加、删除、修改、无法完成
    project_user = models.ManyToManyField(to='UserInfo', through="ProjectUser",
                                          through_fields=('project', 'user'))  # 定义多对多字段

class ProjectUser(models.Model):
    # 项目参与者
    project = models.ForeignKey(verbose_name='项目', to='Project', on_delete=models.CASCADE)
    user = models.ForeignKey(verbose_name='参与者', to='UserInfo', on_delete=models.CASCADE)
    star = models.BooleanField(verbose_name='星标', default=False)
    create_datetime = models.DateTimeField(verbose_name='加入时间', auto_now_add=True)

2、离线脚本

scripts.py专门放脚本文件。

在base.py中:

离线脚本的模版
import django
import os
import sys

base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bugmanagment.settings")
django.setup()  # os.environ['DJANGO_SETTINGS_MODULE']

在init_price_policy中:

初始化价格策略
import base  # 调用base
from app01 import models

def run():
    exists = models.PricePolicy.objects.filter(category=1, title="个人免费版").exists()
    if not exists:
        models.PricePolicy.objects.create(
            category=1,
            title="个人免费版",
            price=0,
            project_num=3,
            project_member=2,
            project_space=20,
            per_file_size=5
        )

if __name__ == '__main__':
    run()

3、用户注册【对前面的代码进行修改】

  • 以前:创建用户
  • 现在:用户&交易记录(获得免费版的额度)
def register(request):
    # 注册
    if request.method == 'GET':
        form = RegisterModelForm()
        return render(request, 'web/register.html', {'form': form})
    # print(request.POST)  # 后台拿到的数据,传到ModelForm进行校验

    form = RegisterModelForm(data=request.POST)
    if form.is_valid():
        # 验证通过后,写入数据库(密码要是密文)
        # instance = form.save,在数据库中新增一条数据,并将新增的这条数据赋值给instance,指的是当前我们添加的这条数据的用户对象
        # 相当于models.UserInfo.objects.filter(id=1).first()

        # 用户表中新建一条数据(注册)
        # form.instance.password ="iudasndfiajsd;fj" #在保存之前将instance中的password进行重置
        instance = form.save()  # 自动剔除数据库中没有的字段

        # 创建交易记录
        policy_object = models.PricePolicy.objects.filter(category=1, title="个人免费版").first() #通过离线脚本添加的数据,取到价格策略的对象
        models.Transaction.objects.create(
            status=2,
            order=str(uuid.uuid4()),
            user=instance,
            price_policy=policy_object,
            count=0,
            price=0,
            start_datetime=datetime.datetime.now() #开始时间为当前时间

        )

        return JsonResponse({'status': True, 'data': '/web/login/'})
    return JsonResponse({'status': False, 'error': form.errors})

4、添加项目

4.1 项目列表母版+样式

  • 后台:登录成功之后才可以访问
  • 官网:都可以访问
  • 通过中间件+白名单 对后台管理的权限进行处理
  • 当前的拥有的价格策略【额度】

轻量级bug管理平台——管理中心

模态对话框要用ajax请求,而不能用form表单提交。

所有代码:

在母版manage.html中:

{#管理中心模版#}
{% load static %}
"en">

    "UTF-8">
    {% block title %}{% endblock %}
    "stylesheet" href="{% static 'plugin/bootstrap/css/bootstrap.min.css' %}">
    "stylesheet" href="{% static 'plugin/font-awesome/css/font-awesome.min.css' %}">

    
    {% block css %} {% endblock %}



{% block content %} {% endblock %}



{% block  js %} {% endblock %}

在project_list中:

{% extends 'layout/manage.html' %}
{% block  css %}
    
{% endblock %}

{% block  content %}
    

    
    
class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
class="modal-dialog" role="document">
class="modal-content">
class="modal-header">

class="modal-title" id="myModalLabel"> 新建项目

class="modal-body">
"addForm"> {% csrf_token %} {% for field in form %}
class="form-group"> {{ field }} class="error-msg">
{% endfor %}
class="modal-footer">
{% endblock %} {% block js %} {% endblock %}

在views\project.py中:

from django.shortcuts import render

from app01 import models
from web.forms.project import ProjectModelForm
from django.http import JsonResponse

def project_list(request):
    """项目列表"""
    # print(request.transaction.user)
    # print(request.transaction.price_policy.project_num)
    if request.method == "GET":
        return render(request, 'web/project_list.html', {'form': form})
    # POST.对话框的ajax添加项目.

    form = ProjectModelForm(request, data=request.POST)  # 接收到请求(前端是用POST请求),进行表单验证
    if form.is_valid():
        # 验证通过:项目名、颜色、描述+creator谁创建的项目?  其他的内容,项目表中已经有默认值了
        form.instance.creator = request.tracer.user  # 当前登录的用户对象

        # 创建项目
        form.save()  # 在保存之前要让models.py项目表中的字段都有值
        return JsonResponse({'status': True})

    return JsonResponse({'status': False, 'error': form.errors})  # 校验失败,返回错误信息

在forms\project.py中

from django import forms
from app01 import models
from web.forms.bootstrap import BootStrapForm
from django.core.exceptions import ValidationError

class ProjectModelForm(BootStrapForm, forms.ModelForm):
    # desc = forms.CharField(widget=forms.Textarea())

    class Meta:
        model = models.Project
        fields = ['name', 'color', 'desc']
        widgets = {
            'desc': forms.Textarea
        }
    #ModelForm里没有request,要重写init方法,在接口传一个request进来
    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    def clean_name(self):
        """项目校验"""
        name = self.cleaned_data['name']
        # 1.当前用户(self.request.tracer.user)是否已创建过此类项目(项目名不能重复)?
        # 1.1 所有人是否已创建过这个项目
        # exists = models.Project.objects.filter(name=name).exists()
        # self.request.tracer.user
        exists = models.Project.objects.filter(name=name, creator=self.request.tracer.user).exists()
        if exists:
            raise ValidationError("项目名已存在")
            # 2.当前用户是否还有额度进行创建项目?
            # 最多创建N个项目
            # 项目额度(self.request.tracer.price_policy.project_num)
            # 现在已创建多少项目?
        count = models.Project.objects.filter(creator=self.request.tracer.user).count()

        if count >=self.request.tracer.price_policy.project_num:
            raise ValidationError('项目个数超限,请购买套餐')

        return name

轻量级bug管理平台——管理中心

内容概要:

  • 展示项目
  • 星标项目
  • 添加项目:颜色选择
  • 项目切换&颜色选择
  • 项目切换&项目管理菜单处置
  • *wiki管理

1、展示项目:

轻量级bug管理平台——管理中心

1.1数据

1、从数据库中获取两部分数据

我创建的所有项目:含有已星标,未星标项目

我参与的所有项目:含有已星标,未星标项目

2、提取已星标项目

列表 = 循环 【我创建的所有项目】+【我参与的所有项目】把已星标的数据提取

3、页面渲染循环三组数据进行页面展示。

得到三个列表 : 星标、创建、参与

2、星标项目(去除星标)

2.1星标

我创建的项目:表中Project的star=True

我参与的项目:表中ProjectUser的star=True

2.2移除星标

我创建的项目:表中Project的star=False 我参与的项目:表中ProjectUser的star=False

3.选择颜色

颜色的选择将表中choice默认生成的select标签改成radio标签.

3.1、部分样式应用BootStrap

面向对象的继承,在form和ModelForm中进行样式的设置
class BootStrapForm(object):
    bootstrap_class_exclude = []  # 支持某个字段不加样式

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():  # 循环字段进行样式的设置
            if name in self.bootstrap_class_exclude:  # 不运用bootstrap样式
                continue
            field.widget.attrs['class'] = 'form-control'
            field.widget.attrs['placeholder'] = '请输入%s' % (field.label,)
class ProjectModelForm(BootStrapForm, forms.ModelForm):
    bootstrap_class_exclude = ['color']  # 走BootStrapForm中的init方法,把颜色的样式排除掉,此为不走BootStrapForm样式的方法
      class Meta:
        model = models.Project
        fields ="_all_"

3.2定制ModelForm的插件(不用django默认提供的插件,不来自django的forms中)

class ProjectModelForm(BootStrapForm, forms.ModelForm):

    class Meta:
        model = models.Project
        fields = "_all_"
        widgets = {
            'desc': forms.Textarea,
            'color': ColorRadioSelect(attrs={'class': 'color-radio'})
        }

注:’desc’利用的是默认的插件,color用的是自定义的插件。

from django.forms import RadioSelect

class ColorRadioSelect(RadioSelect):

    template_name = 'widgets/color_radio/radio.html'
    option_template_name = 'widgets/color_radio/radio_option.html'
自定义样式:在radio.html中:
{% with  id=widget.attrs.id %}
    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 %}
                if option.attrs.id %} for="{{ option.attrs.id }}"{% endif %}>
                    {% include option.template_name with widget=option %}

            {% endfor %}
        {% endfor %}

{% endwith %}

在radio_option.html中:

{% include 'django/forms/widgets/input.html' %}
class="cycle" style="background-color: {{ option.label }}">

3.3项目选择颜色

  • 就是3.1、3.2的关于知识点的应用+前端样式的编写

4、切换菜单

1.数据库中获取

  我创建的:

  我参与的:

2.循环显示

3.当前页面需要显示/其他页面也需要显示【模版中自定义的方法——inclusion_tag】

代码如下 :

在templatetags\project.py中:

from django.template import Library

from app01 import models

register = Library()

@register.inclusion_tag('inclusion/all_project_list.html')
def all_project_list(request):
    # 1.获取我创建的所有项目
    my_project_list = models.Project.objects.filter(creator=request.tracer.user)
    # 2.获取我参与的所有项目
    join_project_list = models.ProjectUser.objects.filter(user=request.tracer.user)
    # return {'my': [], 'join': []} #返回一个这样的字典.

    return {'my': my_project_list, 'join': join_project_list}

运用all_project_list这个inclusion_tag后,返回模版

在all_project_list.html中

class="nav navbar-nav">

    class="dropdown active">
        "#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
           aria-expanded="false">项目 class="caret">
        class="dropdown-menu">
{#            my有值才展示#}
            {% if my %}
                class="fa fa-list" aria-hidden="true">我创建的项目
                {% for item in my %}
                    "#">{{ item.name }}
                {% endfor %}
                "separator" class="divider">
            {% endif %}
            {% if join %}
                class="fa fa-handshake-o" aria-hidden="true">我参与的项目

                {% for item in join %}
                    "#">{{ item.project.name }}
                {% endfor %}

                "separator" class="divider">
            {% endif %}
            "{% url 'project_list' %}">所有项目

在母版manage.html中:插入两行代码即可

{% all_project_list request %}
            {#调用inclusion_tag的时候记得要传入参数request#}

5.项目管理

写上它的多个功能以及他的路由url:

/manage/项目ID/dashboard

/manage/项目ID/issues

/manage/项目ID/statistics

/manage/项目ID/file

/manage/项目ID/wiki

/manage/项目ID/setting

5.1 进入项目展示菜单

  • 进入项目
  • 展示菜单

5.1.1 是否进入项目?【访问url前通过访问中间件进行判断】

  • 判断URL是否以manage开头 [以它开头的就是进入了]
  • project_id是我创建or我参与的 (否则进入的很可能是别人的项目或者进不去)

轻量级bug管理平台——管理中心

5.1.2 显示菜单

依赖:是否已经进入项目?(即request.tracer.project有值表明进入了项目)

class="nav navbar-nav">
                "#">产品功能
                "#">企业方案
                "#">帮助文档
                "#">价格

5.1.3 修复bug

5.1.4 默认选中菜单

总结

  • 项目实现思路
  • 星标/取消星标
  • inclusion_tag实现项目切换
  • 项目菜单
  • 中间件 process_view
  • 点击后默认选中菜单:基于inclusion_tag选中
  • 路由分发
    • include(”xxx.url”)
    • include([ssfdsds,sdf]) #列表,找对应关系
    • 颜色选择:源码+扩展【实现】 (了解即可) 其他的方法例如 :通过下拉框,或者通通过页面自己循环写input框

Original: https://www.cnblogs.com/zhouhuimin99/p/16673386.html
Author: 费皿啊
Title: 轻量级bug管理平台——管理中心

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/603860/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • pytest学习day01- 用例的前后置

    ———————pyest用例的前后置————————————— """…

    Python 2023年9月13日
    049
  • 关于pdd_zues接口probuf,zip处理后传输如何写

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/pythonywy/p/16292794.htmlAut…

    Python 2023年6月15日
    068
  • Django+Layui+Mysql数据可视化系统项目(一)

    部署Django项目 解决数据可视化项目Django创建和使用的问题 一、创建项目 方式一:使用命令行 (cmd) 创建项目 1. 选择位置 先选择一个一个存放项目的位置,直接使用…

    Python 2023年8月4日
    095
  • python pygame鼠标点击_python学习之GUI(pygame鼠标)

    鼠标的位置和其他PyGame的程序一样使用坐标来表示。坐标的值经常使用x和y变量来表示。左上角的坐标值是0,0,x和y的值随着鼠标的向右和向下的移动而增加。 打印鼠标左键点击位置i…

    Python 2023年9月23日
    043
  • MySQL_远程连接的坑与路

    前言:受朋友之托,帮他解决一个远程连接不上mysql的问题,本来想着这是一个很常见的问题,只需要修改下配置文件的,以前也碰到过,但是时间间隔的有点久了,还是有些生疏了,特此记录碰到…

    Python 2023年6月9日
    076
  • Python打包exe

    阅读文本大概需要 10 分钟 前言 必备的python貌似下载最快的地方:直接下载 安装pyinstaller 首先安装pyinstaller,使用安装命令:pip3 instal…

    Python 2023年8月1日
    045
  • 基于python pygame实现的雨点动画

    这是一个我用来教我7岁小俊马的雨点例程,2022年网络上已经宣传未来小学生都将会python了,那么我们这些爸爸还不赶快学吗? 说句实话我本意是觉得小孩子就是先学好数理化就行了,编…

    Python 2023年9月18日
    054
  • Django根据已有数据库表生成模型

    setting.py文件中配置默认连接的数据 DATABASES = { "default" : { "ENGINE":"djan…

    Python 2023年8月5日
    063
  • pytest

    1、pytest的流程和一些命名要求 2、pytest的执行 举例pycharm File –》Settings –》Tools –》Pytho…

    Python 2023年9月14日
    052
  • Scrapy爬虫框架学习笔记

    是一个基于Python的开源网络 ,可以帮助开发者快速地开发和部署 应用程序。它具有强大的数据提取能力、高效的爬取速度和分布式部署等特点,被广泛应用于数据挖掘、信息监控、搜索引擎等…

    Python 2023年10月3日
    051
  • 学习笔记:多模态

    1.多模态数据: 不同的存在形式或信息来源均可被称之为一种模态。由两种或两种以上模态组成的数据称之为多模态数据(多模态用来表示不同形态的数据形式,或者同种形态不同的格式,一般表示文…

    Python 2023年10月1日
    044
  • windows环境Visual Studio2019, C++ & matplotlib

    matplotlib是python的常用库,想在C++环境对该库进行使用,借助matplotlib-cpp来实现, https://github.com/lava/matplotl…

    Python 2023年9月3日
    062
  • 深度学习入门:基于Python的理论与实现——第一章Python入门

    本文为深度学习入门:基于Python的理论与实现的学习笔记,由于笔者已有matalb、c\c++,java相关语言基础,故只记录不同之处需要注意的地方,供给有其他有语言基础,没学过…

    Python 2023年8月31日
    079
  • 云数据库FinOps实战复盘

    历时三个多月的HBase成本优化项目按照预期交付了,HBase云数据库月度成本下降了32.5%,超出预期达成目标。 我们对本次HBase成本优化项目进行深度复盘,并进一步尝试总结云…

    Python 2023年10月13日
    046
  • Python模块与包

    1.模块 1.1模块介绍 2.模块导入 1.3__name__ 2.包 2.1什么是包 2.2导入包语法 2.3导入包的本质 2.4__init__文件 1.1模块介绍 在计算机程…

    Python 2023年8月6日
    068
  • 为什么python打开pygame秒关闭后在运行_python – 几秒后Pygame窗口没有响应

    几秒钟后(大约5秒),这段简单的代码崩溃(窗口没有响应). import pygame from pygame.locals import * pygame.init() scre…

    Python 2023年9月24日
    068
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球