简体   繁体   English

显示一个表格,将 model 实例显示为行,并让用户 select 实例(行)删除

[英]display a table showing model instances as rows and let users select instances (rows) to delete

In my app, users can upload files.在我的应用程序中,用户可以上传文件。 These files are represented by a model with attributes for associated meta-data (upload time, file name, user created note, max value, etc).这些文件由 model 表示,具有相关元数据的属性(上传时间、文件名、用户创建的注释、最大值等)。

A user will upload several files and I want to show them a table of their uploaded files with a checkbox next to each row that can be used to delete selected files and associated model instances.用户将上传几个文件,我想向他们展示他们上传的文件的表格,每行旁边都有一个复选框,可用于删除选定的文件和关联的 model 实例。

I'm not sure what the right approach is, I've looked at the following options but there doesn't seem to be an obvious solution:我不确定正确的方法是什么,我查看了以下选项,但似乎没有明显的解决方案:

  1. model forms, using CheckboxSelectMultiple model forms,使用 CheckboxSelectMultiple

  2. django_tables2 - seems to be an established 3rd party app django_tables2 - 似乎是一个成熟的 3rd 方应用程序

  3. reuse the django admin code (form and view).重用 django 管理代码(表单和视图)。

The default django admin app behavior is perfect for my use case, but I'm not sure what the best way is to reproduce it?默认的 django 管理应用程序行为非常适合我的用例,但我不确定重现它的最佳方法是什么?

app/models.py应用程序/模型.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)

app/admin.py应用程序/admin.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'
    )

app/forms.py应用程序/forms.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,
        }

To achieve what you want to do, you need to create a form that encapsulates a table.要实现您想要做的事情,您需要创建一个封装表格的表单。 When the for loop iterates over each item from your database, provide a checkbox which value would be the unique ID of the uploaded file.当 for 循环遍历数据库中的每个项目时,请提供一个复选框,该复选框的值将是上传文件的唯一 ID。 By submitting the form, you would also then be submitting these IDs.通过提交表单,您也将提交这些 ID。

So this would be your view:所以这将是你的观点:

<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>

Once the user has selected one or multiple checkboxes, and after pressing on delete, you will receive a query dict with the IDs of the selected items that you'll be able to process as you want in your view:一旦用户选择了一个或多个复选框,并且在按下删除后,您将收到一个查询字典,其中包含所选项目的 ID,您可以在视图中按需要处理:

<QueryDict: {'csrfmiddlewaretoken': [''], 'selected': ['2', '3']}>

As for the form, I don't really see any use of it IMO.至于表格,我真的看不出它有什么用海事组织。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM