Django 中如何管理外键文件上传

96 阅读2分钟

在一个 Django 项目中,我们定义了两个模型:Activity 和 File。其中,Activity 模型表示活动,File 模型表示文件。每个活动可以拥有 0 个、1 个或多个文件。现在,我们想要在 Activity 模型的表单中显示一个文件上传按钮,并处理上传的文件。

2、解决方案

为了在 Activity 模型的表单中显示一个文件上传按钮,我们可以使用 django-file-upload 库。该库为 Django 提供了文件上传功能。

首先,我们需要安装 django-file-upload 库:

pip install django-file-upload

然后,我们需要在 settings.py 文件中添加以下内容:

INSTALLED_APPS += (
    'file_upload',
)

接下来,我们需要修改 Activity 模型的表单类。我们可以创建一个新的表单类,也可以继承自 Django 提供的 ModelForm 类。例如,我们可以创建一个名为 ActivityForm 的表单类:

from django import forms
from .models import Activity
from file_upload.forms import FileUploadForm

class ActivityForm(forms.ModelForm):
    files = FileUploadForm()

    class Meta:
        model = Activity
        fields = ('title', 'files')

在 ActivityForm 表单类中,我们使用 FileUploadForm() 方法创建了一个文件上传字段。该字段允许用户上传多个文件。

最后,我们需要在视图中处理上传的文件。例如,我们可以创建一个名为 activity_create 的视图函数:

from django.shortcuts import render, redirect
from .models import Activity
from .forms import ActivityForm

def activity_create(request):
    if request.method == 'POST':
        form = ActivityForm(request.POST, request.FILES)
        if form.is_valid():
            activity = form.save()
            for file in request.FILES.getlist('files'):
                File.objects.create(activity=activity, file=file)
            return redirect('activity_list')
    else:
        form = ActivityForm()

    return render(request, 'activity_create.html', {'form': form})

在 activity_create 视图函数中,我们首先检查请求方法是否为 POST。如果是,则表示用户提交了表单。然后,我们使用 ActivityForm() 方法创建了一个表单对象,并使用 request.POST 和 request.FILES 参数对表单对象进行初始化。

接下来,我们使用 form.is_valid() 方法检查表单是否合法。如果是,则表示表单数据有效,我们可以使用 form.save() 方法保存表单数据。

最后,我们使用一个 for 循环来遍历 request.FILES.getlist('files') 中的文件。对于每个文件,我们使用 File.objects.create() 方法创建了一个 File 对象,并将该对象与当前活动关联起来。

代码例子:

# models.py
class Activity(Model):
    title = CharField(max_length=40)

class File(Model):
    file = FileField(upload_to='files/')
    activity = ForeignKey(Activity)


# forms.py
from django import forms
from .models import Activity
from file_upload.forms import FileUploadForm

class ActivityForm(forms.ModelForm):
    files = FileUploadForm()

    class Meta:
        model = Activity
        fields = ('title', 'files')


# views.py
from django.shortcuts import render, redirect
from .models import Activity
from .forms import ActivityForm

def activity_create(request):
    if request.method == 'POST':
        form = ActivityForm(request.POST, request.FILES)
        if form.is_valid():
            activity = form.save()
            for file in request.FILES.getlist('files'):
                File.objects.create(activity=activity, file=file)
            return redirect('activity_list')
    else:
        form = ActivityForm()

    return render(request, 'activity_create.html', {'form': form})