【问题标题】:display a table showing model instances as rows and let users select instances (rows) to delete显示一个表格,将模型实例显示为行,并让用户选择要删除的实例(行)
【发布时间】:2020-06-02 16:11:20
【问题描述】:

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

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

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

  1. 模型表单,使用 CheckboxSelectMultiple

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

  3. 重用 django 管理代码(表单和视图)。

默认的 django 管理应用程序行为非常适合我的用例,但我不确定重现它的最佳方法是什么?

app/models.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

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

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

【问题讨论】:

    标签: python django python-3.x django-forms django-tables2


    【解决方案1】:

    要实现您想要做的,您需要创建一个封装表格的表单。当 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,您可以在视图中随意处理:

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

    至于表格,我真的看不出它在 IMO 有什么用处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-18
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 2023-03-20
      • 2013-06-20
      • 1970-01-01
      相关资源
      最近更新 更多