号外号外,基于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)
生成后不要忘记这两步:
这里我们就不自己在数据库生成数据了,和任务管理一样,提交后就存入到数据库。
{% extends 'layout.html' %}
{% block content %}
{% endblock %}
{% block js %}
{% endblock %}
继续完善模态框内容:
class OrderModelForm(BootStrapModelForm, forms.ModelForm):
class Meta:
model = models.Order
exclude = ["oid"]
在modal body中新增如下:
{% for field in form %}
{{field}}
{{field.errors.0}}
{% endfor %}
最后效果:
这里和任务管理一样,采用的ajax请求,使用的是模态框。
{% extends 'layout.html' %}
{% block content %}
{% endblock %}
{% block js %}
{% 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))
注意,数据多基本上是一个单独的页面,但是数据少,那就是模态框。
之前我们在写删除的时候,是点击删除按钮,就将该行的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)
编辑其实和添加差不多奥!
所以此处,我编辑和添加使用的同一个对话框。
但是有一个问题,那就是当你点击这个对话框的保存时,怎么确定是编辑还是添加呢?
为此我们应该再设置一个全局变量,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绘图比较方便,很多样例官网都有相应的代码,只是对于需要更改的数据,可以通过ajax发送请求传递数据,此处不多讲,详细内容看官网。
echarts官网链接
文件上传的提出,是因为有这样的需求。
比如你浏览网站,有时候收集信息,不是说让你填写表单,而是让你上传文件,那就要使用文件上传的内容了。
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 %}
{% endblock %}