新增文件上传

master
11617 2 years ago
parent a70fb3d702
commit 1131c7705d
  1. 25
      App/migrations/0022_packageupload.py
  2. 17
      App/migrations/0023_remove_packageupload_package_desc.py
  3. 10
      App/models.py
  4. 2
      App/urls.py
  5. 66
      App/views.py
  6. BIN
      static/images/package.jpg
  7. BIN
      static/images/video.jpg
  8. 31
      templates/function/user.html
  9. 17
      templates/index.html
  10. 41
      templates/nav/dashboard.html
  11. 4
      templates/nav/upload.html
  12. 19
      templates/register.html
  13. 21
      templates/template.html

@ -0,0 +1,25 @@
# Generated by Django 3.2.9 on 2022-10-13 01:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('App', '0021_alter_videoupload_video_title'),
]
operations = [
migrations.CreateModel(
name='packageUpload',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('username', models.CharField(max_length=100)),
('package_time', models.DateTimeField(auto_now_add=True)),
('package_title', models.CharField(max_length=200, unique=True)),
('package_size', models.IntegerField(default=0)),
('package_desc', models.TextField(default='')),
('downloads', models.IntegerField(default=0)),
],
),
]

@ -0,0 +1,17 @@
# Generated by Django 3.2.9 on 2022-10-13 02:13
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('App', '0022_packageupload'),
]
operations = [
migrations.RemoveField(
model_name='packageupload',
name='package_desc',
),
]

@ -74,3 +74,13 @@ class videoUpload(models.Model):
video_image = models.URLField(max_length=10000, default='')
def __str__(self):
return self.username
class packageUpload(models.Model):
username = models.CharField(max_length=100)
package_time = models.DateTimeField(auto_now_add=True)
package_title = models.CharField(max_length=200, unique=True)
package_size = models.IntegerField(default=0)
#package_desc = models.TextField(default="")
downloads = models.IntegerField(default=0)
def __str__(self):
return self.username

@ -24,4 +24,6 @@ urlpatterns = [
# static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
path('videoView/', views.stream_video, name='stream_video'),
path('videoDownload/<id>', views.videoDownload, name='videoDownload'),
path('packagelist/', views.packagelist, name='packagelist'),
path('packageDownload/<id>', views.packageDownload, name='packageDownload'),
]

@ -39,7 +39,16 @@ def login(request):
password = form.cleaned_data.get('loginPass')
user = authenticate(username=username, password=password)
auth.login(request, user)
info = getAddr(request.META['REMOTE_ADDR'])
#info = getAddr(request.META['REMOTE_ADDR'])
info = {
"status": "success",
"query": "none",
"city": "none",
"country": "none",
"regionName": "none",
"lat": "none",
"lon": "none"
}
if info['status'] == 'success':
Login.objects.create(username=username, client_addr=info['query'], city=info['city'],
country=info['country'], region=info['regionName'], latitude=info['lat'],
@ -59,7 +68,9 @@ def userinfo(request):
image_data = Upload.objects.filter(username=request.user.username).order_by('-upload_time')[:5]
blog_data = paper.objects.filter(username=request.user.username).order_by('-paper_time')[:5]
task_data = Task.objects.filter(username=request.user.username).order_by('-task_time')[:5]
return render(request, 'function/user.html', {'name': auth.get_user(request).username, 'login_data': login_data, 'image_data': image_data, 'blog_data': blog_data, 'task_data': task_data, 'regtime': auth.get_user(request).date_joined})
video_data = videoUpload.objects.filter(username=request.user.username).order_by('-video_time')[:5]
package_data = packageUpload.objects.filter(username=request.user.username).order_by('-package_time')[:5]
return render(request, 'function/user.html', {'name': auth.get_user(request).username, 'login_data': login_data, 'image_data': image_data, 'blog_data': blog_data, 'task_data': task_data, 'video_data': video_data, 'package_data': package_data, 'regtime': auth.get_user(request).date_joined})
def logout(request):
@ -81,13 +92,12 @@ def register(request):
email = request.POST.get('email')
password = form.cleaned_data.get('password')
likes = request.POST.getlist('like')
role = request.POST.get('role')
role = "False"
try:
User.objects.create_user(username=username, email=email, password=password, first_name=first_name,
last_name=last_name, is_staff=role, likes=likes)
except Exception as e:
return render(request, 'register.html', {'errors': e})
return redirect(reverse('App:login'))
else:
return render(request, 'register.html', {'errors': form.errors})
@ -121,6 +131,9 @@ def dashboard(request, type):
elif type == 'video':
data = getData(username, t, 'video')
table = videoUpload.objects.order_by('-video_time').all()[:100]
elif type == 'package':
data = getData(username, t, 'package')
table = packageUpload.objects.order_by('package_time').all()[:100]
else:
data = table = ""
return render(request, 'nav/dashboard.html', {'data': data, 'table': table, 'type': type})
@ -172,6 +185,26 @@ def upload(request):
Upload.objects.create(username=auth.get_user(request).username, file_name=file.name, file_path=file.name,file_size=file.size, url_path=url_path['url']).save()
data = {'success': 1, 'message': "上传成功", 'url': url_path['url']}
return JsonResponse(data)
elif ftype == 'package':
file = request.FILES.getlist('file', None)
data = {'status': 'success', 'msg': []}
file_path = os.path.join(settings.MEDIA_ROOT, 'package')
for i in file:
if not os.path.exists(file_path):
os.makedirs(file_path)
file_path = os.path.join(file_path, i.name)
package = packageUpload.objects.filter(username=auth.get_user(request).username,package_title=i.name,package_size=i.size)
if package.exists():
package.update(username=auth.get_user(request).username)
else:
try:
packageUpload.objects.create(username=auth.get_user(request).username, package_title=i.name, package_size=i.size).save()
with open(file_path, 'wb') as f:
for chunk in i.chunks():
f.write(chunk)
except Exception as e:
print(e)
return JsonResponse(data)
else:
file = request.FILES.getlist('file', None)
data = {'status': 'success', 'msg': []}
@ -199,10 +232,13 @@ def getData(username, time, type='login'):
data.update({str(date): paper.objects.filter(paper_time__startswith=date).count()})
elif type == 'video':
data.update({str(date): videoUpload.objects.filter(video_time__startswith=date).count()})
elif type == 'package':
data.update({str(date): packageUpload.objects.filter(package_time__startswith=date).count()})
print(data)
return data
def getAddr(ip):
def getAddr(ip=None):
ip = requests.get('https://httpbin.org/ip').json()['origin']
info = requests.get('http://ip-api.com/json/' + ip + '?lang=zh-CN')
info = info.json()
@ -347,5 +383,23 @@ def videoDownload(request, id):
response = FileResponse(file)
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{}"'.format(quote(file_name))
#messages.error(request, '下载成功')
return response
def packagelist(request):
data = packageUpload.objects.all().order_by('package_time')
return render(request, 'nav/packagelist.html', {'data': data})
def packageDownload(request, id):
try:
data = packageUpload.objects.filter(id=id)
data.update(downloads=data.get().downloads+1)
file_path = os.path.join(settings.MEDIA_ROOT, 'package', data.get().package_title)
file_name = os.path.basename(file_path)
file = open(file_path, 'rb')
response = FileResponse(file)
response['Content-Type'] = 'application/octet-stream'
response['Content-Disposition'] = 'attachment;filename="{}"'.format(quote(file_name))
return response
except Exception as e:
print(e)
return HttpResponse('内部错误')

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

@ -15,11 +15,19 @@
<h1>你好,{{ name }}</h1>
<p class="fs-5 col-md-8">本站点功能依旧在开发当中,欢迎你的使用及反馈,以下为你在本站的操作轨迹。</p>
<p class="fs-5 col-md-8">注册时间:{{ regtime }}</p>
<hr style="border: 5px solid blue;"/>
<p>版本更新日志:v1.10.11</p>
<p>1、版本修改了登录逻辑,不在记录非公网的登录位置</p>
<p>2、优化注册页面</p>
<p>3、新增文件上传下载功能</p>
<p>4、优化了图片显示方式</p>
<p>5、用户界面添加视频及文件归档</p>
<p>6、增加仪表盘界面的文件上传数据</p>
<div class="mb-5">
<a href="{% url 'App:repassword' %}" class="btn btn-primary btn-lg px-4">修改密码</a>
</div>
<hr class="col-3 col-md-2 mb-5">
<hr style="border: 5px solid blue;"/>
<div class="row g-5">
<div class="col-md-6">
@ -32,6 +40,26 @@
{% endfor %}
</ul>
</div>
<div class="col-md-6">
<h2>文件存储</h2>
<p>显示5次最近文件上传时数据,获取所有数据查看{% url 'App:packagelist' %}</p>
<ul class="icon-list">
{% for i in package_data %}
<li>上传时间:{{ i.package_time }}&nbsp;&nbsp;下载地址: <a href="{% url 'App:packageDownload' i.id %}">{{ i.package_title }}</a>
</li>
{% endfor %}
</ul>
</div>
<div class="col-md-6">
<h2>视频存储</h2>
<p>显示5次最近视频上传数据,获取所有数据查看{% url 'App:videoList' %}</p>
<ul class="icon-list">
{% for i in video_data %}
<li>上传时间:{{ i.video_time }}&nbsp;&nbsp;观看地址:<a href="{% url 'App:videoView' i.id %}">{{ i.video_title }}</a>
</li>
{% endfor %}
</ul>
</div>
<div class="col-md-6">
<h2>图床数据</h2>
<p>最近5次,获取所有数据查看<a href="{% url 'App:image' %}">我的相册</a></p>
@ -65,6 +93,7 @@
{% endfor %}
</ul>
</div>
<hr style="border: 5px solid blue;"/>
</div>
</div>
{% endblock %}

@ -7,9 +7,6 @@
<link rel="stylesheet" href="{% static 'css/station/carousel.css' %}">
{% endblock %}
{% block login %}
{# <script>#}
{# alert('本次更新:\n1、修复上传视频重复问题')#}
{# </script>#}
<header style="padding-top: 70px">
<div class="px-3 py-2 border-bottom mb-3">
<div class="container d-flex flex-wrap justify-content-center">
@ -119,7 +116,7 @@
<rect width="100%" height="100%" fill="#777"/>
</img>
<h2>事件处理</h2>
<h2>任务处理</h2>
<p>请在规定时间内完成规定任务,此功能仅支持内部使用,任务下达会在课堂中提醒,任务完成过程中请截图保留。未完成将得到奖励、</p>
<p><a class="btn btn-secondary" href="{% url 'App:listTask' %}">点击查看</a></p>
</div><!-- /.col-lg-4 -->
@ -135,7 +132,17 @@
</div><!-- /.col-lg-4 -->
<div class="col-lg-4">
<img class="bd-placeholder-img rounded-circle" width="140" height="140"
src="{% static 'images/paper.jpg' %}" role="img" aria-label="Placeholder: 140x140"
src="{% static 'images/package.jpg' %}" role="img" aria-label="Placeholder: 140x140"
preserveAspectRatio="xMidYMid slice" focusable="false"></img>
<h2>文件上传</h2>
<p>课程文件上传<a
href="{% url 'App:packagelist' %}">文件库</a></p>
<p><a class="btn btn-secondary" href="{% url 'App:upload' %}?type=package">立即上传</a></p>
</div><!-- /.col-lg-4 -->
<div class="col-lg-4">
<img class="bd-placeholder-img rounded-circle" width="140" height="140"
src="{% static 'images/video.jpg' %}" role="img" aria-label="Placeholder: 140x140"
preserveAspectRatio="xMidYMid slice" focusable="false"></img>
<h2>视频上传</h2>

@ -36,15 +36,9 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<a class="nav-link" href="{% url 'App:dashboard' 'package' %}?time=week">
<span data-feather="bar-chart-2"></span>
Reports
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">
<span data-feather="layers"></span>
Integrations
文件上传
</a>
</li>
</ul>
@ -211,6 +205,37 @@
</tbody>
</table>
</div>
{% elif type == 'package' %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">文件数据</h1>
</div>
<canvas class="my-4 w-100" id="myChart" width="900" height="380"></canvas>
<h2>[仅显示最近100条]</h2>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col">上传时间</th>
<th scope="col">上传用户</th>
<th scope="col">文件标题</th>
<th scope="col">文件大小</th>
<th scope="col">下载量</th>
</tr>
</thead>
<tbody>
{% for i in table %}
<tr>
<td>{{ i.package_time }}</td>
<td>{{ i.username }}</td>
<td>{{ i.package_title }}</td>
<td>{{ i.package_size |filesizeformat }}</td>
<td>{{ i.downloads }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
</main>
</div>

@ -34,7 +34,7 @@
theme: 'fas',
language: 'zh',
uploadUrl: '{% url 'App:upload' %}?type={{ type }}',
allowedFileExtensions: ['jpg', 'png', 'gif','mp4'],
allowedFileExtensions: ['jpg', 'png', 'gif','mp4', 'gz', 'zip', 'exe', 'xz', 'tar'],
uploadExtraData: function () {
return {
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
@ -62,7 +62,7 @@
$("#test-upload").fileinput({
'theme': 'fas',
'showPreview': false,
'allowedFileExtensions': ['jpg', 'png', 'gif','mp4'],
'allowedFileExtensions': ['jpg', 'png', 'gif','mp4', 'gz', 'zip', 'exe', 'xz', 'tar'],
'elErrorContainer': '#errorBlock'
});

@ -108,9 +108,8 @@
<div class="col-12">
<label for="username" class="form-label">登陆用户名</label>
<div class="input-group has-validation">
<span class="input-group-text">@</span>
<input type="text" class="form-control" id="username" name="username" value=""
placeholder="建议填写邮箱前缀" required>
placeholder="用于登录" required>
<div class="invalid-feedback">
用户名必须填写
</div>
@ -142,22 +141,6 @@
{% endif %}
<hr class="my-4">
<h4 class="mb-3">来宾类型</h4>
<div class="my-3">
<div class="form-check">
<input id="credit" name="role" value="0" type="radio" class="form-check-input" checked
required>
<label class="form-check-label" for="credit">外部来访</label>
</div>
<div class="form-check">
<input id="debit" name="role" value="1" type="radio" class="form-check-input" required>
<label class="form-check-label" for="debit">云计算学员</label>
</div>
</div>
<hr class="my-4">
<button class="w-100 btn btn-primary btn-lg" type="submit">注册</button>
</div>
</div>

@ -82,6 +82,10 @@
<path d="M14.5 3a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h13zm-13-1A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-13z"/>
<path d="M7 5.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm-1.496-.854a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 1 1 .708-.708l.146.147 1.146-1.147a.5.5 0 0 1 .708 0zM7 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm-1.496-.854a.5.5 0 0 1 0 .708l-1.5 1.5a.5.5 0 0 1-.708 0l-.5-.5a.5.5 0 0 1 .708-.708l.146.147 1.146-1.147a.5.5 0 0 1 .708 0z"/>
</symbol>
<symbol id="package" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
class="bi bi-archive" viewBox="0 0 16 16">
<path d="M0 2a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1v7.5a2.5 2.5 0 0 1-2.5 2.5h-9A2.5 2.5 0 0 1 1 12.5V5a1 1 0 0 1-1-1V2zm2 3v7.5A1.5 1.5 0 0 0 3.5 14h9a1.5 1.5 0 0 0 1.5-1.5V5H2zm13-3H1v2h14V2zM5 7.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5z"/>
</symbol>
</svg>
<main>
@ -137,6 +141,14 @@
视频站
</a>
</li>
<li>
<a href="{% url 'App:packagelist' %}" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
<use xlink:href="#package"/>
</svg>
文件库
</a>
</li>
<li>
<a href="{% url 'App:paperList' %}" class="nav-link text-white">
<svg class="bi d-block mx-auto mb-1" width="24" height="24">
@ -189,11 +201,14 @@
<li class="nav-item mb-2"><a href="https://tool.lu/" class="nav-link p-0 text-muted"
target="_blank">开发小工具</a></li>
<li class="nav-item mb-2"><a href="https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial"
class="nav-link p-0 text-muted" target="_blank">SQL在线练习</a></li>
class="nav-link p-0 text-muted" target="_blank">SQL在线练习</a>
</li>
<li class="nav-item mb-2"><a href="https://console.apipost.cn/login"
class="nav-link p-0 text-muted" target="_blank">API调试工具</a></li>
class="nav-link p-0 text-muted" target="_blank">API调试工具</a>
</li>
<li class="nav-item mb-2"><a href="https://interview.beyourself.org.cn/command/list/"
class="nav-link p-0 text-muted" target="_blank">Linux命令检索</a></li>
class="nav-link p-0 text-muted" target="_blank">Linux命令检索</a>
</li>
</ul>
</div>

Loading…
Cancel
Save