upload avatar
@@ -1,10 +1,12 @@
|
||||
from django.http import JsonResponse
|
||||
from django.http import JsonResponse, HttpResponseForbidden
|
||||
from django.contrib import auth
|
||||
from django.contrib.auth.models import User
|
||||
from .models import Avatar
|
||||
|
||||
|
||||
def signup(request):
|
||||
if request.method != 'POST':
|
||||
return HttpResponseForbidden()
|
||||
username = request.POST.get('username')
|
||||
password = request.POST.get('password')
|
||||
if not username:
|
||||
@@ -23,6 +25,8 @@ def signup(request):
|
||||
|
||||
|
||||
def signin(request):
|
||||
if request.method != 'POST':
|
||||
return HttpResponseForbidden()
|
||||
username = request.POST.get('username')
|
||||
password = request.POST.get('password')
|
||||
if not username:
|
||||
@@ -38,11 +42,15 @@ def signin(request):
|
||||
|
||||
|
||||
def logout(request):
|
||||
if request.method != 'POST':
|
||||
return HttpResponseForbidden()
|
||||
auth.logout(request)
|
||||
return JsonResponse({'result': 'success'})
|
||||
|
||||
|
||||
def changePsw(request):
|
||||
if request.method != 'POST':
|
||||
return HttpResponseForbidden()
|
||||
old_psw = request.POST.get('old_psw')
|
||||
new_psw = request.POST.get('new_psw')
|
||||
if not old_psw:
|
||||
@@ -56,3 +64,19 @@ def changePsw(request):
|
||||
user.set_password(new_psw)
|
||||
user.save()
|
||||
return JsonResponse({'result': 'success', 'uid': user.id})
|
||||
|
||||
|
||||
def changeAvatar(request):
|
||||
if request.method != 'POST':
|
||||
return HttpResponseForbidden()
|
||||
|
||||
image = request.FILES.get("upload-avatar", None)
|
||||
if image is None:
|
||||
return JsonResponse({'error': 'No File'})
|
||||
|
||||
# 修改文件名字
|
||||
image.name = str(request.user) + '.' + image.name.split('.')[-1]
|
||||
a = request.user.avatar
|
||||
a.avatar = image
|
||||
a.save()
|
||||
return JsonResponse({})
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 2.1.5 on 2019-01-19 02:39
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('chatbot', '0002_auto_20190115_1420'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Avatar',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('avatar', models.ImageField(default='default.png', upload_to='')),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,5 +1,8 @@
|
||||
import os
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.dispatch import receiver
|
||||
|
||||
|
||||
class ChatHistory(models.Model):
|
||||
@@ -12,3 +15,21 @@ class ChatHistory(models.Model):
|
||||
class Avatar(models.Model):
|
||||
user = models.OneToOneField(to=User, on_delete=models.CASCADE)
|
||||
avatar = models.ImageField(default='avatar/default.png', upload_to='avatar')
|
||||
|
||||
|
||||
@receiver(models.signals.pre_save, sender=Avatar)
|
||||
def auto_delete_file_on_change(sender, instance, **kwargs):
|
||||
"""Deletes file from filesystem
|
||||
when corresponding `MediaFile` object is changed.
|
||||
"""
|
||||
if not instance:
|
||||
return False
|
||||
try:
|
||||
old_file = Avatar.objects.get(user=instance.user).avatar
|
||||
except Avatar.DoesNotExist:
|
||||
return False
|
||||
|
||||
new_file = instance.avatar
|
||||
if not old_file == new_file:
|
||||
if os.path.isfile(old_file.path):
|
||||
os.remove(old_file.path)
|
||||
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 847 B |
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,101 @@
|
||||
/*!
|
||||
* FileInput Chinese Translations
|
||||
*
|
||||
* This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or
|
||||
* any HTML markup tags in the messages must not be converted or translated.
|
||||
*
|
||||
* @see http://github.com/kartik-v/bootstrap-fileinput
|
||||
* @author kangqf <kangqingfei@gmail.com>
|
||||
*
|
||||
* NOTE: this file must be saved in UTF-8 encoding.
|
||||
*/
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
$.fn.fileinputLocales['zh'] = {
|
||||
fileSingle: '文件',
|
||||
filePlural: '个文件',
|
||||
browseLabel: '选择 …',
|
||||
removeLabel: '移除',
|
||||
removeTitle: '清除选中文件',
|
||||
cancelLabel: '取消',
|
||||
cancelTitle: '取消进行中的上传',
|
||||
uploadLabel: '上传',
|
||||
uploadTitle: '上传选中文件',
|
||||
msgNo: '没有',
|
||||
msgNoFilesSelected: '未选择文件',
|
||||
msgCancelled: '取消',
|
||||
msgPlaceholder: '选择 {files}...',
|
||||
msgZoomModalHeading: '详细预览',
|
||||
msgFileRequired: '必须选择一个文件上传.',
|
||||
msgSizeTooSmall: '文件 "{name}" (<b>{size} KB</b>) 必须大于限定大小 <b>{minSize} KB</b>.',
|
||||
msgSizeTooLarge: '文件 "{name}" (<b>{size} KB</b>) 超过了允许大小 <b>{maxSize} KB</b>.',
|
||||
msgFilesTooLess: '你必须选择最少 <b>{n}</b> {files} 来上传. ',
|
||||
msgFilesTooMany: '选择的上传文件个数 <b>({n})</b> 超出最大文件的限制个数 <b>{m}</b>.',
|
||||
msgFileNotFound: '文件 "{name}" 未找到!',
|
||||
msgFileSecured: '安全限制,为了防止读取文件 "{name}".',
|
||||
msgFileNotReadable: '文件 "{name}" 不可读.',
|
||||
msgFilePreviewAborted: '取消 "{name}" 的预览.',
|
||||
msgFilePreviewError: '读取 "{name}" 时出现了一个错误.',
|
||||
msgInvalidFileName: '文件名 "{name}" 包含非法字符.',
|
||||
msgInvalidFileType: '不正确的类型 "{name}". 只支持 "{types}" 类型的文件.',
|
||||
msgInvalidFileExtension: '不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.',
|
||||
msgFileTypes: {
|
||||
'image': 'image',
|
||||
'html': 'HTML',
|
||||
'text': 'text',
|
||||
'video': 'video',
|
||||
'audio': 'audio',
|
||||
'flash': 'flash',
|
||||
'pdf': 'PDF',
|
||||
'object': 'object'
|
||||
},
|
||||
msgUploadAborted: '该文件上传被中止',
|
||||
msgUploadThreshold: '处理中...',
|
||||
msgUploadBegin: '正在初始化...',
|
||||
msgUploadEnd: '完成',
|
||||
msgUploadEmpty: '无效的文件上传.',
|
||||
msgUploadError: '上传出错',
|
||||
msgValidationError: '验证错误',
|
||||
msgLoading: '加载第 {index} 文件 共 {files} …',
|
||||
msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.',
|
||||
msgSelected: '{n} {files} 选中',
|
||||
msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.',
|
||||
msgImageWidthSmall: '图像文件的"{name}"的宽度必须是至少{size}像素.',
|
||||
msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.',
|
||||
msgImageWidthLarge: '图像文件"{name}"的宽度不能超过{size}像素.',
|
||||
msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.',
|
||||
msgImageResizeError: '无法获取的图像尺寸调整。',
|
||||
msgImageResizeException: '调整图像大小时发生错误。<pre>{errors}</pre>',
|
||||
msgAjaxError: '{operation} 发生错误. 请重试!',
|
||||
msgAjaxProgressError: '{operation} 失败',
|
||||
ajaxOperations: {
|
||||
deleteThumb: '删除文件',
|
||||
uploadThumb: '上传文件',
|
||||
uploadBatch: '批量上传',
|
||||
uploadExtra: '表单数据上传'
|
||||
},
|
||||
dropZoneTitle: '拖拽文件到这里 …',
|
||||
dropZoneClickTitle: '<br>(或点击{files}按钮选择文件)',
|
||||
fileActionSettings: {
|
||||
removeTitle: '删除文件',
|
||||
uploadTitle: '上传文件',
|
||||
downloadTitle: '下载文件',
|
||||
uploadRetryTitle: '重试',
|
||||
zoomTitle: '查看详情',
|
||||
dragTitle: '移动 / 重置',
|
||||
indicatorNewTitle: '没有上传',
|
||||
indicatorSuccessTitle: '上传',
|
||||
indicatorErrorTitle: '上传错误',
|
||||
indicatorLoadingTitle: '上传 ...'
|
||||
},
|
||||
previewZoomButtonTitles: {
|
||||
prev: '预览上一个文件',
|
||||
next: '预览下一个文件',
|
||||
toggleheader: '缩放',
|
||||
fullscreen: '全屏',
|
||||
borderless: '无边界模式',
|
||||
close: '关闭当前预览'
|
||||
}
|
||||
};
|
||||
})(window.jQuery);
|
||||
@@ -42,4 +42,16 @@ function changePsw() {
|
||||
t.show();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$("#upload-avatar").fileinput({
|
||||
theme: "fas",
|
||||
language: 'zh',
|
||||
allowedFileExtension: ['jpg', 'png'],
|
||||
resizeImage: true,
|
||||
maxFileCount: 1,
|
||||
uploadUrl: 'uploadavatar',
|
||||
uploadExtraData: {csrfmiddlewaretoken: Cookies.get('csrftoken')}
|
||||
});
|
||||
});
|
||||
@@ -12,6 +12,12 @@
|
||||
<script type="text/javascript" src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'js/bootstrap.min.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'js/user_center.js' %}"></script>
|
||||
|
||||
<link rel="stylesheet" href="{% static 'css/fileinput.min.css'%}" media="all" type="text/css" />
|
||||
<link rel="stylesheet" href="{% static 'css/awesomefont.css' %}">
|
||||
<script src="{% static 'js/file_input/piexif.min.js' %}" type="text/javascript"></script>
|
||||
<script src="{% static 'js/file_input/fileinput.min.js' %}"></script>
|
||||
<script src="{% static 'js/file_input/zh.js' %}"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -39,6 +45,7 @@
|
||||
<a href="#" class="btn btn-primary">上传新头像</a>
|
||||
</div>
|
||||
</div>
|
||||
<input id="upload-avatar" type="file" name="upload-avatar">
|
||||
</div>
|
||||
<div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab">
|
||||
<form>
|
||||
|
||||
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 37 KiB |
@@ -31,6 +31,7 @@ urlpatterns = [
|
||||
path('signin', chatbot.auth.signin),
|
||||
path('logout', chatbot.auth.logout),
|
||||
path('changepsw', chatbot.auth.changePsw),
|
||||
path('uploadavatar', chatbot.auth.changeAvatar),
|
||||
|
||||
path('chat', chatbot.func.chat),
|
||||
path('separation', chatbot.func.separation),
|
||||
|
||||