显示一个将模型实例显示为行的表,并允许用户选择要删除的实例(行)



在我的应用程序中,用户可以上传文件。这些文件由具有相关元数据属性(上传时间、文件名、用户创建的注释、最大值等(的模型表示。

用户将上传多个文件,我想向他们展示他们上传的文件表,每行旁边都有一个复选框,可用于删除所选文件和关联的模型实例。

我不确定正确的方法是什么,我已经查看了以下选项,但似乎没有明显的解决方案:

  1. 模型窗体, 使用复选框选择多个

  2. django_tables2 - 似乎是一个成熟的第三方应用程序

  3. 重用 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的任何用途。

最新更新