文件上传
目录
1. 配置文件上传的路径
2. 实现上传文件功能
3.代码展示集合
这篇文章, 我们会讲到如何去上传文件。里面的细节点, 需要注意下, 博主就在配置文件上, 卡了很长时间的bug, 这篇文章里面也会讲到博主遇到bug的点。
一、配置文件上传的路径
我们打开settings.py:
在最后面加上两行代码:
import os
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
这两行代码, 是用来设置将来文件上传玩以后, 把上传好的文件放到哪里, 我们在那两行代码的配置信息里面不难看出, 我们是将上传好的文件, 都存放在media文件夹里面。
我们在项目的根目录下新建一个media文件夹。
然后我们还需要文件上传的相应路由:
urls.py:
"""project_simple URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings
from project_one.views import depart, user, assets, admin_role, login, Ajax_data, task_data, perform
urlpatterns = [
re_path(r"^media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT})
]
这里运用了正则表达式, 来匹配要访问文件的路由, 用正则表达式^media/(?P<path>.*)$
来表示。
这里面需要导入以下包:
1.from django.urls import path, re_path
2.from django.views.static import serve
3.from django.conf import settings
以上两个步骤, 在做今天的项目之前, 一定要配置好, 不然到后面调试程序的时候, 都不清楚哪里报错了, 博主就是因为这个问题, 卡了很久。。。。。。
二、实现上传文件功能
创建数据库表格Perform(这个是记录业绩的表格):
models.py:
class Perform(models.Model):
oid = models.CharField(verbose_name="订单号", max_length=32)
source = models.CharField(verbose_name="销售", max_length=32)
title = models.CharField(verbose_name="客户姓名", max_length=32)
times = models.DateField(verbose_name="成交日期")
price = models.CharField(verbose_name="成交金额", max_length=32)
name = models.CharField(verbose_name="销售人员", max_length=32)
image = models.CharField(verbose_name="详情", max_length=128)
我们先要实现页面展示功能:
perform_list.html:
{% extends "index/model_tmp.html" %}
{#{% load static %}#}
{% block content %}
<div class="container">
<a href="/perform/add/" class="btn btn-success">添加信息</a>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">绩效表</h3>
</div>
<div class="panel-body">
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>订单号</th>
<th>客户来源</th>
<th>客户名称</th>
<th>成交时间</th>
<th>成交价格</th>
<th>销售人员</th>
<th>详情</th>
{% if request.unicom_role == 3 %}
<th>操作</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for data in perform_list %}
<tr>
<th scope="row">{{ data.id }}</th>
<th>{{ data.oid }}</th>
<th>{{ data.source }}</th>
<th>{{ data.title }}</th>
<th>{{ data.times }}</th>
<th>{{ data.price }}</th>
<th>{{ data.name }}</th>
<th>
<div><a target="_blank" href="/{{ data.image }}/" style="width: 60px; height: 60px;"><img style="object-fit: cover; border-radius: 100px;" src="/{{ data.image }}/" width="60" height="60" alt="图片无法加载"></a></div>
</th>
{% if request.unicom_role == 3 %}
<td style="color: green">
<a href="#"><span style="color: green;" class="glyphicon glyphicon-pencil" aria-hidden="true"></span></a>
<a href="#"><span style="color: red;" class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{# 实现分页查询 #}
<ul class="pagination">
{{ page_string }}
</ul>
</div>
{% endblock %}
PageData.py(这个代码之前写过, 这篇文章中需要用到此代码):
from copy import deepcopy
from django.utils.safestring import mark_safe
class PageData(object):
def __init__(self, request, queryset, page_size=10, plus=2, page_param="page"):
get_query_dict = deepcopy(request.GET)
self.query_dict = get_query_dict
self.page_param = page_param
page = request.GET.get(self.page_param, "1")
# 判段当前page首部是纯数字
if page.isdecimal():
page = int(page)
else:
page = 1
self.page = page
self.start = (self.page - 1) * page_size
self.end = self.page * page_size
self.page_queryset = queryset[self.start: self.end]
page_count = queryset.count()
page_count, div = divmod(page_count, page_size)
if div:
page_count += 1
self.page_count = page_count
self.plus = plus
def page_html(self):
if self.page_count <= 2 * self.plus + 1:
start_page = 1
end_page = self.page_count
else:
# 如果当前点击的页面是小于3的
if self.page <= self.plus:
start_page = 1
end_page = 2 * self.plus + 1
else:
# 后五页
if (self.page + self.plus) > self.page_count:
start_page = self.page_count - self.plus * 2
end_page = self.page_count
else:
# 大于前五页,小于后五也的其他页面
start_page = self.page - self.plus
end_page = self.page + self.plus
page_str_list = []
# 首页
self.query_dict.setlist(self.page_param, [1])
page_str_list.append(f'<li><a href="?{self.query_dict.urlencode()}">首页</a></li>')
# 上一页
if self.page > 1:
self.query_dict.setlist(self.page_param, [self.page - 1])
page_str_list.append(
f'<li><a href="?{self.query_dict.urlencode()}"><span aria-hidden="true">«</span></a></li>')
else:
page_str_list.append(f'<li class="disabled"><span aria-hidden="true">«</span></li>')
for page_num in range(start_page, end_page + 1):
if page_num == self.page:
self.query_dict.setlist(self.page_param, [page_num])
page_str_list.append(f'<li class="active"><a href="?{self.query_dict.urlencode()}">{page_num}</a></li>')
else:
self.query_dict.setlist(self.page_param, [page_num])
page_str_list.append(f'<li><a href="?{self.query_dict.urlencode()}">{page_num}</a></li>')
# 下一页
if self.page < self.page_count:
self.query_dict.setlist(self.page_param, [self.page + 1])
page_str_list.append(
f'<li><a href="?{self.query_dict.urlencode()}"><span aria-hidden="true">»</span></a></li>')
else:
page_str_list.append(f'<li class="disabled"><span aria-hidden="true">»</span></li>')
# 尾页
self.query_dict.setlist(self.page_param, [self.page_count])
page_str_list.append(f'<li><a href="?{self.query_dict.urlencode()}">尾页</a></li>')
search_page = """
<li>
<div style="float: right">
<form method="get">
<div class="input-group" style="width: 100px;float: right">
<input type="text" class="form-control" name="page">
<span class="input-group-btn">
<button class="btn btn-success" type="submit">跳转</button>
</span>
</div>
</form>
</div>
</li>
"""
page_str_list.append(search_page)
page_string = mark_safe("".join(page_str_list))
return page_string
perform.py:
from datetime import datetime
from django.shortcuts import render, redirect
from django import forms
from project_one.utils.PageData import PageData
import os
from project_one import models
# Create your views here.
def perform_info(request):
perform_list = models.Perform.objects.all()
# 这个PageData分页, 在utils代码里面。
page_object = PageData(request, perform_list)
content = {
"perform_list": page_object.page_queryset,
"page_string": page_object.page_html()
}
return render(request, "perform/perform_list.html", content)
绩效数据添加功能:
我们先自定义form:
class PerformForm(forms.Form):
oid = forms.CharField(label="订单号",
widget=forms.TextInput(attrs={"class": "form-control", "autocomplete": "off"}))
source = forms.CharField(label="客户来源",
widget=forms.TextInput(attrs={"class": "form-control", "autocomplete": "off"}))
title = forms.CharField(label="客户名称",
widget=forms.TextInput(attrs={"class": "form-control", "autocomplete": "off"}))
price = forms.CharField(label="成交价格",
widget=forms.TextInput(attrs={"class": "form-control", "autocomplete": "off"}))
image = forms.FileField(label="详情")
这里我们没有写class Meta这个类, 所以我们需要用到Form而不是ModelForm。
添加函数:
def add_perform(request):
if request.method == "GET":
title = "添加绩效"
form = PerformForm()
content = {"title": title, "form": form}
return render(request, "perform/perform_add_modify.html", content)
# 如果要上传文件的话, request.FILES千万不能漏掉
form = PerformForm(data=request.POST, files=request.FILES)
if form.is_valid():
# 获取提交过来的文件对象
image_object = form.cleaned_data.get("image")
# 拼接路径
# image_object.name这个就是文件名字,
# os.path.join("media", image_object.name)就代表用media文件夹拼接文件名字,
# 也就是把路径变为:文件夹/文件名。
# 但是最后的路径为:文件夹\文件名。所以需要把\替换成/, 注意要写成\\,
# 因为反斜杠它在正则表达式里面本身就有自己的意义, 所以这里需要转义操作。
print(os.path.join("media", image_object.name))
file_path = os.path.join("media", image_object.name).replace("\\", "/")
print(file_path)
# 将文件存储在media目录当中
with open(file_path, "wb") as file:
for chunk in image_object.chunks():
file.write(chunk)
oid = form.cleaned_data.get("oid")
source = form.cleaned_data.get("source")
title = form.cleaned_data.get("title")
times = datetime.now().strftime("%Y-%m-%d")
price = form.cleaned_data.get("price")
name = request.session['info']['username']
models.Perform.objects.create(oid=oid, source=source, title=title, times=times, price=price, name=name, image=file_path)
return redirect("/perform/list/")
return render(request, "perform/perform_add_modify.html", {"form": form})
这里有些细节需要注意:
- files=request.FILES不能漏加, 因为我们在添加数据的时候, 要上传文件。
- 拼接路径的写法, 利用os.path.join来实现, 最后不要忘记用replace函数把反斜杠\替换成斜杠/。
- 将文件存储到media里面, 需要用到文件存储的代码, 里面用chunk来遍历存储, 因为只有request请求, 才具有.content存储, 那这里, 我们只能用chunk来解决。
- 添加数据, 需要获取到相关的所有数据, oid订单号, source客户来源, title客户名称, times成交时间(获取当前时间, 然后再用年-月-日的格式存储), price成交价格, name销售人员, image就是file_path(文件路径)。
perform_add_modify.html:
{% extends "index/model_tmp.html" %}
{% load static %}
{% block css %}
<link rel="stylesheet" href="{% static 'css/layui.css' %}">
{% endblock %}
{% block content %}
<div class="container">
<h1>{{ title }}</h1>
{# 由于我们enctype="multipart/form-data"必须要加 #}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
{# field.label这里面就是获取我们在models.py里面创建表格里面的每一个字段里面有个verbose_name这个参数的值 #}
<label for="exampleInputEmail1">{{ field.label }}</label>
{{ field }}
{# 展示错误信息 #}
<span style="color: red">{{ field.errors.0 }}</span>
<br>
{% endfor %}
<button type="submit" class="btn btn-success">提交</button>
</form>
</div>
{% endblock %}
这里面也有个细节需要注意下, 由于我们需要再添加数据的时候, 上传文件, 那我们就需要在form表单里面, 加上enctype="multipart/form-data"
。
最后我们不要忘记添加路由:
urls.py:
"""project_simple URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings
from project_one.views import depart, user, assets, admin_role, login, Ajax_data, task_data, perform
urlpatterns = [
re_path(r"^media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT})
path("perform/list/", perform.perform_info, name="perform_info"),
path("perform/add/", perform.add_perform, name="add_perform")
]
还有, 不要忘记在model_tmp.html的header里面添加绩效那栏。
<ul class="nav navbar-nav">
{% if request.unicom_role == 1 %}
<li class="active"><a href="/depart/">部门页面</a></li>
<li class="active"><a href="/user/">员工页面</a></li>
{% elif request.unicom_role == 3%}
<li class="active"><a href="/depart/">部门页面</a></li>
<li class="active"><a href="/user/">员工页面</a></li>
<li class="active"><a href="/assets_list/">资产页面</a></li>
{% endif %}
{# <li class="active"><a href="/depart/">部门页面</a></li>#}
{# <li class="active"><a href="/user/">员工页面</a></li>#}
{# <li class="active"><a href="/assets_list/">资产页面</a></li>#}
<li class="dropdown">
{% if request.unicom_role == 3 %}
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">平台用户<span class="caret"></span></a>
{% endif %}
<ul class="dropdown-menu">
<li><a href="/admin_list/">登录账号</a></li>
<li><a href="/demo/list/">ajax请求</a></li>
</ul>
</li>
<li class="active"><a href="/task/list/">任务列表</a></li>
<li class="active"><a href="/perform/list/">绩效</a></li>
</ul>
运行结果:
我们登录管理员账号之后, 在上面的导航栏里面点击绩效:
然后点击添加信息:
文件的话, 自己随便从电脑里面选择一个文件。
提交(添加)数据:
数据添加成功!!!
我们再点击一下详情:
会帮我们打开我们上传的文件, 我们这里上传的是图片。
三、代码展示合集
前端:
perform_list.html:
{% extends "index/model_tmp.html" %}
{#{% load static %}#}
{% block content %}
<div class="container">
<a href="/perform/add/" class="btn btn-success">添加信息</a>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">绩效表</h3>
</div>
<div class="panel-body">
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>订单号</th>
<th>客户来源</th>
<th>客户名称</th>
<th>成交时间</th>
<th>成交价格</th>
<th>销售人员</th>
<th>详情</th>
{% if request.unicom_role == 3 %}
<th>操作</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for data in perform_list %}
<tr>
<th scope="row">{{ data.id }}</th>
<th>{{ data.oid }}</th>
<th>{{ data.source }}</th>
<th>{{ data.title }}</th>
<th>{{ data.times }}</th>
<th>{{ data.price }}</th>
<th>{{ data.name }}</th>
<th>
<div><a target="_blank" href="/{{ data.image }}/" style="width: 60px; height: 60px;"><img style="object-fit: cover; border-radius: 100px;" src="/{{ data.image }}/" width="60" height="60" alt="图片无法加载"></a></div>
</th>
{% if request.unicom_role == 3 %}
<td style="color: green">
<a href="#"><span style="color: green;" class="glyphicon glyphicon-pencil" aria-hidden="true"></span></a>
<a href="#"><span style="color: red;" class="glyphicon glyphicon-trash" aria-hidden="true"></span></a>
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{# 实现分页查询 #}
<ul class="pagination">
{{ page_string }}
</ul>
</div>
{% endblock %}
perform_add_modify:
{% extends "index/model_tmp.html" %}
{% load static %}
{% block css %}
<link rel="stylesheet" href="{% static 'css/layui.css' %}">
{% endblock %}
{% block content %}
<div class="container">
<h1>{{ title }}</h1>
{# 由于我们enctype="multipart/form-data"必须要加 #}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
{# field.label这里面就是获取我们在models.py里面创建表格里面的每一个字段里面有个verbose_name这个参数的值 #}
<label for="exampleInputEmail1">{{ field.label }}</label>
{{ field }}
{# 展示错误信息 #}
<span style="color: red">{{ field.errors.0 }}</span>
<br>
{% endfor %}
<button type="submit" class="btn btn-success">提交</button>
</form>
</div>
{% endblock %}
model_tmp.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
{% block css %}
{% endblock %}
</head>
<body>
<div class="navbar navbar-default">
<div class="container">
<!-- 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" href="#">管理系统</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
{% if request.unicom_role == 1 %}
<li class="active"><a href="/depart/">部门页面</a></li>
<li class="active"><a href="/user/">员工页面</a></li>
{% elif request.unicom_role == 3%}
<li class="active"><a href="/depart/">部门页面</a></li>
<li class="active"><a href="/user/">员工页面</a></li>
<li class="active"><a href="/assets_list/">资产页面</a></li>
{% endif %}
{# <li class="active"><a href="/depart/">部门页面</a></li>#}
{# <li class="active"><a href="/user/">员工页面</a></li>#}
{# <li class="active"><a href="/assets_list/">资产页面</a></li>#}
<li class="dropdown">
{% if request.unicom_role == 3 %}
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">平台用户<span class="caret"></span></a>
{% endif %}
<ul class="dropdown-menu">
<li><a href="/admin_list/">登录账号</a></li>
<li><a href="/demo/list/">ajax请求</a></li>
</ul>
</li>
<li class="active"><a href="/task/list/">任务列表</a></li>
<li class="active"><a href="/perform/list/">绩效</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">欢迎-->{{ request.session.info.username }}<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="/logout/">退出登录</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</div>
{% block content %}
{% endblock %}
<script src="{% static 'js/jquery3.7.1.js' %}"></script>
<script src="{% static 'js/bootstrap.js' %}"></script>
{% block js %}
{% endblock %}
</body>
</html>
后端:
models.py:
from django.db import models
# Create your models here.
class Department(models.Model):
title = models.CharField(verbose_name="部门名称", max_length=255)
def __str__(self):
return self.title
class UserInfo(models.Model):
name = models.CharField(verbose_name="姓名", max_length=255)
gender_choices = (
(1, "男"), (2, "女")
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
salary = models.IntegerField(verbose_name="薪水")
age = models.IntegerField(verbose_name="年龄")
create_time = models.DateField(verbose_name="入职时间")
department = models.ForeignKey(verbose_name="部门", max_length=255, to="Department", to_field="id",
on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.name
class Assets(models.Model):
mobile = models.CharField(verbose_name="手机号", max_length=11)
status_code_choice = (
(1, "已使用"),
(2, "未使用")
)
status = models.SmallIntegerField(verbose_name="状态", choices=status_code_choice)
create_time = models.DateField(verbose_name="创建时间")
user = models.ForeignKey(to="UserInfo", to_field="id", verbose_name="使用者", on_delete=models.SET_NULL, null=True, blank=True)
price = models.CharField(verbose_name="价格", max_length=10)
class AdminRole(models.Model):
username = models.CharField(verbose_name="用户名", max_length=32)
password = models.CharField(verbose_name="密码", max_length=64)
password_choice = (
(1, "员工"),
(2, "领导"),
(3, "管理员")
)
role = models.SmallIntegerField(verbose_name="角色", choices=password_choice)
class Task(models.Model):
title = models.CharField(verbose_name="标题", max_length=64)
level_choice = {
(1, "临时任务"),
(2, "普通任务"),
(3, "重要任务"),
(4, "紧急任务")
}
level = models.SmallIntegerField(verbose_name="任务级别", choices=level_choice)
detail = models.TextField(verbose_name="任务内容")
user = models.ForeignKey(verbose_name="负责人", to="UserInfo", on_delete=models.CASCADE, null=True, blank=True)
times = models.DateField(verbose_name="开始时间")
code_choices = {
(1, "未完成"),
(2, "正在处理"),
(3, "已完成")
}
code = models.SmallIntegerField(verbose_name="任务状态", choices=code_choices)
class Perform(models.Model):
oid = models.CharField(verbose_name="订单号", max_length=32)
source = models.CharField(verbose_name="销售", max_length=32)
title = models.CharField(verbose_name="客户姓名", max_length=32)
times = models.DateField(verbose_name="成交日期")
price = models.CharField(verbose_name="成交金额", max_length=32)
name = models.CharField(verbose_name="销售人员", max_length=32)
image = models.CharField(verbose_name="详情", max_length=128)
perform.py:
from datetime import datetime
from django.shortcuts import render, redirect
from django import forms
from project_one.utils.PageData import PageData
import os
from project_one import models
# Create your views here.
def perform_info(request):
perform_list = models.Perform.objects.all()
page_object = PageData(request, perform_list)
content = {
"perform_list": page_object.page_queryset,
"page_string": page_object.page_html()
}
return render(request, "perform/perform_list.html", content)
class PerformForm(forms.Form):
oid = forms.CharField(label="订单号",
widget=forms.TextInput(attrs={"class": "form-control", "autocomplete": "off"}))
source = forms.CharField(label="客户来源",
widget=forms.TextInput(attrs={"class": "form-control", "autocomplete": "off"}))
title = forms.CharField(label="客户名称",
widget=forms.TextInput(attrs={"class": "form-control", "autocomplete": "off"}))
price = forms.CharField(label="成交价格",
widget=forms.TextInput(attrs={"class": "form-control", "autocomplete": "off"}))
image = forms.FileField(label="详情")
def add_perform(request):
if request.method == "GET":
title = "添加绩效"
form = PerformForm()
content = {"title": title, "form": form}
return render(request, "perform/perform_add_modify.html", content)
# 如果要上传文件的话, request.FILES千万不能漏掉
form = PerformForm(data=request.POST, files=request.FILES)
if form.is_valid():
# 获取提交过来的文件对象
image_object = form.cleaned_data.get("image")
# 拼接路径
# image_object.name这个就是文件名字,
# os.path.join("media", image_object.name)就代表用media文件夹拼接文件名字,
# 也就是把路径变为:文件夹/文件名。
# 但是最后的路径为:文件夹\文件名。所以需要把\替换成/, 注意要写成\\,
# 因为反斜杠它在正则表达式里面本身就有自己的意义, 所以这里需要转义操作。
print(os.path.join("media", image_object.name))
file_path = os.path.join("media", image_object.name).replace("\\", "/")
print(file_path)
# 将文件存储在media目录当中
with open(file_path, "wb") as file:
for chunk in image_object.chunks():
file.write(chunk)
oid = form.cleaned_data.get("oid")
source = form.cleaned_data.get("source")
title = form.cleaned_data.get("title")
times = datetime.now().strftime("%Y-%m-%d")
price = form.cleaned_data.get("price")
name = request.session['info']['username']
models.Perform.objects.create(oid=oid, source=source, title=title, times=times, price=price, name=name, image=file_path)
return redirect("/perform/list/")
return render(request, "perform/perform_add_modify.html", {"form": form})
settings.py:
"""
Django settings for project_simple project.
Generated by 'django-admin startproject' using Django 4.1.3.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-m@31x($s*0tgzm0$2(ct6izu)8oe$xa)@k7(&*7tkr*g(dbl)5'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'project_one.apps.ProjectOneConfig'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'project_one.middleware.auth.AuthMiddleware'
]
ROOT_URLCONF = 'project_simple.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'project_simple.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': BASE_DIR / 'db.sqlite3',
# }
# }
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '28_class_03',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = '/static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
UNICOM_PERMISSION = {
1: ["add_depart", "depart_modify", "del_depart", "user_add", "user_modify", "user_del", "user_add_modelform",
"user_modify_modelform", "assets_add", "assets_modify", "assets_del", "admin_add", "admin_modify",
"admin_reset_pwd", "admin_del"],
2: [],
3: []
}
# 这篇文章需要添加的代码
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
注意, settings.py里面, 其他代码都不需要动, 我们也不要轻易修改配置文件里面的代码, 否则会导致整个项目崩溃。
urls.py:
"""project_simple URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from django.views.static import serve
from django.conf import settings
from project_one.views import depart, user, assets, admin_role, login, Ajax_data, task_data, perform
urlpatterns = [
# path('admin/', admin.site.urls),
re_path(r"^media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT}),
path("", depart.index, name="index"),
path("depart/", depart.depart, name="depart"),
path("depart/add/", depart.add_depart, name="add_depart"),
path("depart/<int:nid>/modify/", depart.depart_modify, name="depart_modify"),
path("depart/<int:nid>/del/", depart.del_depart, name="del_depart"),
path("user/", user.user_info, name="user_info"),
path("user/add/", user.user_add, name="user_add"),
path("user/<int:nid>/modify/", user.user_modify, name="user_modify"),
path("user/<int:nid>/del/", user.user_del, name="user_del"),
path("user/add/modelform", user.user_add_modelform, name="user_add_modelform"),
path("user/<int:nid>/modify/modelform", user.user_modify_modelform, name="user_modify_modelform"),
path("assets_list/", assets.assets, name="assets"),
path("assets/add/", assets.assets_add, name="assets_add"),
path("assets/<int:nid>/modify/", assets.assets_modify, name="assets_modify"),
path("assets/<int:nid>/del/", assets.assets_del, name="assets_del"),
path("admin_list/", admin_role.admin, name="admin"),
path("admin/add/", admin_role.admin_add, name="admin_add"),
path("admin/<int:nid>/modify/", admin_role.admin_modify, name="admin_modify"),
path("admin/<int:nid>/reset/pwd/", admin_role.admin_reset_pwd, name="admin_reset_pwd"),
path("admin/<int:nid>/del/", admin_role.admin_del, name="admin_del"),
path("login/", login.login, name="login"),
path("logout/", login.logout, name="logout"),
path("image/code/", login.image_code, name="image_code"),
path("demo/list/", Ajax_data.demo_list, name="demo_list"),
path("demo/one/", Ajax_data.demo_one, name="demo_one"),
path("demo/two/", Ajax_data.demo_two, name="demo_two"),
path("task/list/", task_data.task_list, name="task_list"),
path("task/add/", task_data.task_add, name="task_add"),
path('task/del/', task_data.task_delete, name="task_delete"),
path('task/modify/', task_data.task_modify, name="task_modify"),
path('task/modify/content/', task_data.task_modify_content, name="task_modify_content"),
path("perform/list/", perform.perform_info, name="perform_info"),
path("perform/add/", perform.add_perform, name="add_perform")
]
好了, 这篇文章关于文件上传功能就到此结束了!!!
以上就是Django的文件上传功能的所有内容了, 如果有哪里不懂的地方,可以把问题打在评论区, 欢迎大家在评论区交流!!!
如果我有写错的地方, 望大家指正, 也可以联系我, 让我们一起努力, 继续不断的进步.
学习是个漫长的过程, 需要我们不断的去学习并掌握消化知识点, 有不懂或概念模糊不理解的情况下,一定要赶紧的解决问题, 否则问题只会越来越多, 漏洞也就越老越大.
人生路漫漫, 白鹭常相伴!!!