在我的应用程序中,用户可以上传文件。这些文件由具有相关元数据属性(上传时间、文件名、用户创建的注释、最大值等(的模型表示。
用户将上传多个文件,我想向他们展示他们上传的文件表,每行旁边都有一个复选框,可用于删除所选文件和关联的模型实例。
我不确定正确的方法是什么,我已经查看了以下选项,但似乎没有明显的解决方案:
-
模型窗体, 使用复选框选择多个
-
django_tables2 - 似乎是一个成熟的第三方应用程序
-
重用 Django 管理员代码(窗体和视图(。
默认的 django 管理员应用程序行为非常适合我的用例,但我不确定重现它的最佳方法是什么?
应用/模型.py
import uuid
from django.contrib.auth import get_user_model
from django.db import models
User = get_user_model()
class Document(models.Model):
def rename_file(self, filename):
ext = filename.split('.')[-1]
new_name = uuid.uuid4().hex
return f'documents/{new_name}.{ext}'
owner = models.ForeignKey(
User,
on_delete=models.CASCADE,
editable=True,
)
document = models.FileField(upload_to=rename_file)
notes = models.CharField(max_length=258, blank=True)
uploaded_at = models.DateTimeField(auto_now_add=True)
nice_name = models.CharField(max_length=128, null=True, blank=False)
start_date = models.DateField(null=True, blank=False)
end_date = models.DateField(null=True, blank=False)
def __str__(self):
return str(self.document)
应用/管理员.py
from django.contrib import admin
from .models import Document
def uuid(obj):
return obj.owner.uuid
uuid.short_description = 'user id'
@admin.register(Document)
class DocumentAdmin(admin.ModelAdmin):
fields = ('document', 'notes')
list_display = (
'owner',
uuid,
'document',
'nice_name',
'notes',
'uploaded_at',
'start_date',
'end_date'
)
应用/表单.py
from django import forms
from django.forms.widgets import CheckboxSelectMultiple
from .models import Document
class DeleteDocumentsForm(forms.ModelForm):
document = forms.ModelMultipleChoiceField(queryset=None, widget=forms.CheckboxSelectMultiple)
nice_name = forms.ModelMultipleChoiceField(queryset=None, widget=forms.CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
qs = Document.objects.filter(owner_id=user)
# super(DeleteDocumentsForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.fields['document'].queryset = qs
self.fields['nice_name'].queryset = qs.values('nice_name')
# document.fields['nice_name'].widget.attrs['readonly'] = True
class Meta:
model = Document
fields = ('document', 'nice_name')
widgets = {
'document': CheckboxSelectMultiple,
'nice_name': CheckboxSelectMultiple,
}
要实现您想要执行的操作,您需要创建一个封装表的表单。当 for 循环循环访问数据库中的每个项目时,请提供一个复选框,该值将是上传文件的唯一 ID。通过提交表单,您还将提交这些 ID。
所以这是你的观点:
<form action="." method="post">
{% csrf_token %}
<table>
{% for upload in uploads %}
<tr>
<td><input type="checkbox" name="selected" value="{{ upload.id }}"></td>
<td><img src="{{ upload.url }}" alt="image"></td>
<td>{{ upload.name }}</td>
</tr>
{% endfor %}
</table>
<button type="submit">Delete</button>
</form>
用户选中一个或多个复选框后,在按删除后,您将收到一个查询字典,其中包含所选项目的 ID,您可以在视图中根据需要处理这些项目 ID:
<QueryDict: {'csrfmiddlewaretoken': [''], 'selected': ['2', '3']}>
至于表格,我真的没有看到IMO的任何用途。