基于Pycharm的Django学习 —— 项目实战(对话框、echarts绘图、文件上传)

本文介绍了使用Django框架进行项目实战,涵盖了订单管理的创建、列表展示、删除和编辑功能,以及Echarts绘图和文件上传操作。通过创建Model、视图、模板和JavaScript交互,实现了订单数据的CRUD操作,并利用模态框和Ajax实现无刷新交互。同时,文章还展示了文件上传的实现,文件会被保存到项目根目录。
摘要由CSDN通过智能技术生成

号外号外,基于Pycharm的Django学习,项目实战彩蛋来啦!

我报考的学校,今天下午五点就要出考研成绩了,我好慌,从来没有这么紧张过,我就想着把项目收个尾,这样赶在出成绩之前,也是把Django学完啦。

昨天的后续又完善了一下,在新建任务里面又加了任务列表,提交后就更新:

在这里插入图片描述

订单管理

老规矩,先设计表结构:

class Order(models.Model):
    """订单"""
    # 可以根据下单时间加上随机字符串自动生成订单号
    oid = models.CharField(verbose_name="订单号", max_length=64)
    title = models.CharField(verbose_name="名称", max_length=32)
    price = models.IntegerField(verbose_name="价格")
    status_choices = (
        (1, "待支付"),
        (2, "已支付")
    )
    status = models.SmallIntegerField(verbose_name="订单状态", choices=status_choices, default=1)
    # models.CASCADE没有括号 否则会报错
    admin = models.ForeignKey(verbose_name="管理员", to="Admin", on_delete=models.CASCADE)

生成后不要忘记这两步:

在这里插入图片描述
在数据库查看一下:

在这里插入图片描述
这里我们就不自己在数据库生成数据了,和任务管理一样,提交后就存入到数据库。

order_list

在这里插入图片描述

在这里插入图片描述

{% extends 'layout.html' %}

{% block content %}
<div style="margin-bottom:20px">
    <input id="btnAdd" type="button" value="新建订单" class="btn btn-primary">
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
            </div>
            <div class="modal-body">
                ...
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>

{% endblock %}

{% block js %}
<script type="text/javascript">
        $(function(){
            bindBtnAddEvent();
        })

        function bindBtnAddEvent(){
            $("#btnAdd").click(function(){

                $('#myModal').modal('show');

            });
        }
</script>
{% endblock %}

在这里插入图片描述
这样测试页面就出来了!!

继续完善模态框内容:

class OrderModelForm(BootStrapModelForm, forms.ModelForm):
    class Meta:
        model = models.Order
        exclude = ["oid"]

在这里插入图片描述

在modal body中新增如下:

{% for field in form %}
                <div class="form-group">
                    <label>{{field.label}}</label>
                    {{field}}
                    <span style="color:red;">{{field.errors.0}}</span>
                </div>
                {% endfor %}

最后效果:

在这里插入图片描述

order_add

这里和任务管理一样,采用的ajax请求,使用的是模态框。

{% extends 'layout.html' %}

{% block content %}
<div style="margin-bottom:20px">
    <input id="btnAdd" type="button" value="新建订单" class="btn btn-primary">
</div>

<div>
    <div class="panel panel-default">
        <div class="panel-heading">
            <span class="glyphicon glyphicon-th-list"></span>
            订单列表
        </div>
        <!--可以直接在浏览器中选中元素 copy element-->
        <table class="table table-bordered">
            <thead>
            <tr>
                <th>ID</th>
                <th>订单号</th>
                <th>标题</th>
                <th>价格</th>
                <th>状态</th>
                <th>管理员</th>
            </tr>
            </thead>
            <tbody>
            {% for data in data_list %}
            <tr>
                <th scope="row">{{data.id}}</th>
                <td>{{data.oid}}</td>
                <td>{{data.title}}</td>
                <td>{{data.price}}</td>
                <td>{{data.get_status_display}}</td>
                <td>{{data.admin.username}}</td>
                <td>
                    <a class="btn btn-success btn-xs" href="#">编辑</a>
                    <a class="btn btn-danger btn-xs" href="#">删除</a>
                </td>
            </tr>
            {% endfor %}
            </tbody>
        </table>
    </div>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title" id="myModalLabel">新建订单</h4>
            </div>
            <!--需要展示的内容放在模态对话框里面-->
            <div class="modal-body">
                <form id="formAdd">
                    {% for field in form %}
                    <div class="form-group">
                        <label>{{field.label}}</label>
                        {{field}}
                        <span style="color:red;" class="error-msg">{{field.errors.0}}</span>
                    </div>
                    {% endfor %}
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                <button id="btnSave" type="button" class="btn btn-primary">保存</button>
            </div>
        </div>
    </div>
</div>

{% endblock %}

{% block js %}
<script type="text/javascript">
        $(function(){
            bindBtnAddEvent();
            bindBtnSaveEvent();
        })

        function bindBtnAddEvent(){
            $("#btnAdd").click(function(){

                $('#myModal').modal('show');

            });
        }

        function bindBtnSaveEvent(){
            $("#btnSave").click(function(){

                $(".error-msg").empty();

                $.ajax({
                    url: "/order/add/",
                    type: "post",
                    data: $("#formAdd").serialize(),
                    dataType: "JSON",
                    success: function(res){
                         if(res.status){
                            alert("添加任务成功");
                            $("#formAdd")[0].reset();
                            $('#myModal').modal('hide');
                            location.reload();
                        }else{
                            $.each(res.error,function(name,data){
                                $("#id_"+name).next().text(data[0]);
                            })
                        }
                    }
                })
            });
        }

</script>
{% endblock %}
def order_list(request):
    form = OrderModelForm()
    data_list = models.Order.objects.all()
    content = {
        "form": form,
        "data_list": data_list
    }
    return render(request, "order_list.html", content)


@csrf_exempt
def order_add(request):
    form = OrderModelForm(data=request.POST)
    if form.is_valid():
        # 添加没有提交过来的oid
        form.instance.oid = datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(1000, 9999))
        form.save()
        data_dict = {"status": True}
        # return HttpResponse(json.dumps(data_dict))
        return JsonResponse(data_dict)
    data_dict = {"status": False, "error": form.errors}
    return HttpResponse(json.dumps(data_dict))

在这里插入图片描述
加一个分页吧!

在这里插入图片描述
在这里插入图片描述
注意,数据多基本上是一个单独的页面,但是数据少,那就是模态框。

order_delete

之前我们在写删除的时候,是点击删除按钮,就将该行的id传递给函数,但是这次我们不打算这样处理,我们打算把所有的删除写成一个class,然后使用js来进行处理。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

function bindBtnConfirmDeleteEvent(){
            $("#btnConfirmDelete").click(function(){

                $.ajax({
                    url: "/order/delete/",
                    type: "get",
                    data: {uid:DELETE_ID},
                    dataType: "JSON",
                    success: function(res){
                         alert("删除成功");
                         location.reload();
                    }
                })
            });
        }
# ajax的get可以不用csrf
def order_delete(request):
    uid = request.GET.get("uid")
    models.Order.objects.filter(id=uid).delete()
    data_dict = {"status": True}
    return JsonResponse(data_dict)

在这里插入图片描述

order_edit

编辑其实和添加差不多奥!

所以此处,我编辑和添加使用的同一个对话框。

但是有一个问题,那就是当你点击这个对话框的保存时,怎么确定是编辑还是添加呢?

为此我们应该再设置一个全局变量,EDIT_ID,当点击添加的时候,这个设置为undefined,当点击编辑的时候设置为对应的id,这样就可以根据此变量区分开来了。

# ajax的get可以不用csrf
def order_detail(request):
    uid = request.GET.get("uid")

    # 方法一:
    # row_object = models.Order.objects.filter(id=uid).first()
    # data_dict = {
    #     "status": True,
    #     "data": {
    #         "title": row_object.title,
    #         "price": row_object.price,
    #         "status": row_object.status,
    #         "admin": row_object.admin_id
    #     }
    # }
    # return JsonResponse(data_dict)

    # values相当于obj变成了字典
    row_dict = models.Order.objects.filter(id=uid).values("title", "price", "status", "admin_id").first()
    data_dict = {
        "status": True,
        "data": row_dict
    }
    return JsonResponse(data_dict)


@csrf_exempt
def order_edit(request):
    uid = request.GET.get("uid")
    row_object = models.Order.objects.filter(id=uid).first()
    form = OrderModelForm(data=request.POST, instance=row_object)
    if form.is_valid():
        form.save()
        data_dict = {"status": True}
        return JsonResponse(data_dict)
    data_dict = {"status": False, "error": form.errors}
    return HttpResponse(json.dumps(data_dict))

对应的js代码如下:

function bindBtnSaveEvent(){
            $("#btnSave").click(function(){

                $(".error-msg").empty();

                if(EDIT_ID){
                    doEdit();
                }else{
                    doAdd();
                }


            });
        }

          function doEdit(){
            $.ajax({
                    url: "/order/edit/?uid="+EDIT_ID,
                    type: "post",
                    data: $("#formAdd").serialize(),
                    dataType: "JSON",
                    success: function(res){
                         if(res.status){
                            alert("编辑任务成功");
                            $("#formAdd")[0].reset();
                            $('#myModal').modal('hide');
                            location.reload();
                        }else{
                            $.each(res.error,function(name,data){
                                $("#id_"+name).next().text(data[0]);
                            })
                        }
                    }
                })
        }

        function doAdd(){
            $.ajax({
                    url: "/order/add/",
                    type: "post",
                    data: $("#formAdd").serialize(),
                    dataType: "JSON",
                    success: function(res){
                         if(res.status){
                            alert("添加任务成功");
                            $("#formAdd")[0].reset();
                            $('#myModal').modal('hide');
                            location.reload();
                        }else{
                            $.each(res.error,function(name,data){
                                $("#id_"+name).next().text(data[0]);
                            })
                        }
                    }
                })
        }

在这里插入图片描述

echarts绘图

数据统计这一块使用echarts绘图比较方便,很多样例官网都有相应的代码,只是对于需要更改的数据,可以通过ajax发送请求传递数据,此处不多讲,详细内容看官网。

echarts官网链接

文件上传

文件上传的提出,是因为有这样的需求。

比如你浏览网站,有时候收集信息,不是说让你填写表单,而是让你上传文件,那就要使用文件上传的内容了。

upload_list

def upload_list(request):
    if request.method == "GET":
        return render(request, "upload_list.html")
    print(request.POST)  # 请求体中的数据
    print(request.FILES)  # 请求发过来的文件

    # < QueryDict: {'csrfmiddlewaretoken': ['8bdmV6XCTVyUSGI92LxmVp9iWPIdyKuKTNP0EbqcdOqUIJuSnO2YYPRjlxaFXsDE'],
    #               'username': ['wxm']} >
    # < MultiValueDict: {'avatar': [ < TemporaryUploadedFile: 证件照.jpg(image / jpeg) >]} >

    file_object = request.FILES.get("avatar")
    print(file_object.name)  # 证件照.jpg

    f = open(file_object.name, mode="wb")
    for chunk in file_object.chunks():
        f.write(chunk)
    f.close()

    return HttpResponse("请求成功")

对应的html:

{% extends 'layout.html' %}

{% block content %}
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="text" name="username">
        <input type="file" name="avatar">
        <input type="submit" value="提交">
    </form>
{% endblock %}

在这里插入图片描述
最后它给我上传到我的项目根目录了!

在这里插入图片描述
还有半个小时成绩就出来了,好激动好紧张好慌啊!!

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值