【发布时间】:2020-07-11 05:10:38
【问题描述】:
我有一个多文件上传,并希望将每个用户限制为 3 个上传。我的问题是我需要知道user 已经在数据库中创建了多少文件以及他们当前正在上传多少文件(他们可以一次上传多个文件,并且可以多次上传)。
我尝试了很多事情,包括:
创建一个validator(验证器传递的是要添加的实际文件,而不是model,所以我无法访问model来获取id来调用if StudentUploadedFile.objects.filter(student_lesson_data=data.id).count() >= 4:)。
在clean(self): 中进行验证(clean 一次只传递一个实例,并且数据库不会更新,直到所有文件都被清除,所以我可以计算数据库中已经存在的文件但无法计算当前正在上传多少个)。
使用pre-save 方法(如果在传递给我的pre-save 方法的每个文件之间更新了数据库,它会起作用,但只有在所有上传的文件都通过我的pre-save 方法后才更新数据库)。
我的post-save 尝试:
@receiver(pre_save, sender=StudentUploadedFile)
def upload_file_pre_save(sender, instance, **kwargs):
if StudentUploadedFile.objects.filter(student_lesson_data=instance.data.id).count() >= 4:
raise ValidationError('Sorry, you cannot upload more than three files')
编辑:
models.py
class StudentUploadedFile(models.Model):
student_lesson_data = models.ForeignKey(StudentLessonData, related_name='student_uploaded_file', on_delete=models.CASCADE)
student_file = models.FileField(upload_to='module_student_files/', default=None)
views.py
class StudentUploadView(View):
def get(self, request):
files_list = StudentUploadedFile.objects.all()
return render(self.request, 'users/modules.html', {'student_files': files_list})
def post(self, request, *args, **kwargs):
form = StudentUploadedFileForm(self.request.POST, self.request.FILES)
form.instance.student_lesson_data_id = self.request.POST['student_lesson_data_id']
if form.is_valid():
uploaded_file = form.save()
# pass uploaded_file data and username so new file can be added to students file list using ajax
# lesson_id is used to output newly added file to corresponding newly_added_files div
data = {'is_valid': True, 'username': request.user.username, 'file_id': uploaded_file.id, 'file_name': uploaded_file.filename(),
'lesson_id': uploaded_file.student_lesson_data_id, 'file_path': str(uploaded_file.student_file)}
else:
data = {'is_valid': False}
return JsonResponse(data)
模板.py
<form id='student_uploaded_file{{ item.instance.id }}'>
{% csrf_token %}
<a href="{% url 'download_student_uploaded_file' username=request.user.username file_path=item.instance.student_file %}" target='_blank'>{{ item.instance.filename }}</a>
<a href="{% url 'delete_student_uploaded_file' username=request.user.username file_id=item.instance.id %}" class='delete' id='{{ item.instance.id }}'>Delete</a>
</form>
js
$(function () {
// open file explorer window
$(".js-upload-photos").on('click', function(){
// concatenates the id from the button pressed onto the end of fileupload class to call correct input element
$("#fileupload" + this.id).click();
});
$('.fileupload_input').each(function() {
$(this).fileupload({
dataType: 'json',
done: function(e, data) { // process response from server
// add newly added files to students uploaded files list
if (data.result.is_valid) {
$("#newly_added_files" + data.result.lesson_id).prepend("<form id='student_uploaded_file" + data.result.file_id +
"'><a href='/student_hub/" + data.result.username + "/download_student_uploaded_file/" +
data.result.file_path + "' target='_blank'>" + data.result.file_name + "</a><a href='/student_hub/" + data.result.username +
"/delete_student_uploaded_file/" + data.result.file_id + "/' class='delete' id=" + data.result.file_id + ">Delete</a></form>")
}
}
});
});
更新: forms.py
class StudentUploadedFileForm(forms.ModelForm):
student_file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
view.py
class StudentUploadView(View):
model = StudentUploadedFile
max_files_per_lesson = 3
def post(self, request, *args, **kwargs):
lesson_data_id = request.POST['student_lesson_data_id']
current_files_count = self.model.objects.filter(
student_lesson_data_id=lesson_data_id
).count()
avail = self.max_files_per_lesson - current_files_count
file_list = request.FILES.getlist('student_file')
print(len(file_list))
if avail - len(file_list) < 0:
return JsonResponse(data={
'is_valid': False,
'reason': f'Too many files: you can only upload {avail}.'
})
else:
for f in file_list:
print(f)
data = {'test': True}
return JsonResponse(data)
谢谢。
【问题讨论】:
-
为什么不按 user_id 来计算呢?统计用户过滤的上传数据
-
您的
upload_file_pre_save函数指的是在data_id字段上过滤的UploadedFile模型。您的 models.py 声明了一个带有student_lesson_data字段的StudentUploadedFile模型。这些是一样的吗?还不清楚StudentUploadedFile是如何与您的用户相关联的。StudentLessonData是自定义用户吗? -
对不起,我忘记了我简化了我最初发布的代码以使其更易于理解。我把这些东西修好了,是的,它们是一样的。对于每节课,都会注册一个
Student,他们有一个StudentLessonData对象,其中包含特定于该Student/课程的数据。StudentUploadedFile与StudentLessonData具有一对多关系(一个StudentLessonData可以有多个StudentUploadedFiles)。 -
您的问题表明您希望“将用户限制为每个用户 3 次上传”。是每个
Student3 次上传,还是每个StudentLessonData3 次上传? -
StudentModuleData是从哪里来的?你之前没有提到过那个模型。