如何使用内联表单集通过CreateView上载文件?

2024-04-20 07:39:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我无法使用内联表单集通过CreateView上载文件。你知道吗

理想情况下,它将是多个文件,类似于它在管理页面中的行为,但在这一点上,我试图得到至少一个了。在下面的示例中,一个车间应该能够有多个文件。你知道吗

上传时,除了文件,其他都会保存

你知道吗型号.py你知道吗

...


class Workshop (models.Model):
    title = models.CharField(max_length=120)
    created_by = models.ForeignKey(User)
    slug = models.SlugField(blank=True, null=True, unique=True)

    def __str__(self):
        return self.title

...

def upload_workshop_file_loc(instance, filename):
    slug = instance.workshop.slug
    if not slug:
        slug = unique_slug_generator(instance.workshop)
    location = "workshop/{}/".format(slug)
    return location + filename


class WorkshopFile(models.Model):
    workshop = models.ForeignKey(Workshop, related_name='files', on_delete=models.CASCADE)
    name = models.CharField()
    file = models.FileField(
        upload_to=upload_workshop_file_loc,
        null=True,
        validators=[FileExtensionValidator
(allowed_extensions=['pdf', 'ppt'])]
    )

    def __str__(self):
        return str(self.file.name)

...

你知道吗表单.py你知道吗

from django import forms
from .models import Workshop, WorkshopFile
from django.forms.models import inlineformset_factory


class AddWorkshopForm(forms.ModelForm):

    class Meta:
        model = Workshop
        exclude = []


FileFormSet = inlineformset_factory(Workshop,
WorkshopFile,
fields=['workshop','name', 'file'],
exclude=[], 
extra=1, 
can_delete=True
)

很可能是凶手

你知道吗视图.py你知道吗

...
class AddWorkshopView(LoginRequiredMixin, CreateView):

    model = Workshop
    form_class = AddWorkshopForm
    template_name = "modules/add-workshop.html"
    success_url = "/modules/workshop-list/"

    def post(self, request, *args, **kwargs):
        form = AddWorkshopForm(request.POST, request.FILES)
        workshop = form.save(commit=False)
        workshop.save()
        workshop.created_by = request.user
        return redirect('modules:workshop', workshop.slug)


    def get_context_data(self, **kwargs):
        data = super(AddWorkshopView, self).get_context_data(**kwargs)
        if self.request.POST:
            data['files'] = FileFormSet(self.request.POST)
        else:
            data['files'] = FileFormSet()
        return data


    def form_valid(self, form):
        context = self.get_context_data()
        files = context['files']

        with transaction.atomic():
            form.instance.created_by = self.request.user
            form.instance.updated_by = self.request.user
            self.object = form.save()

        if files.is_valid():
            files.instance = self.object
            files.save()

        return super(AddWorkshopView, self).form_valid(form)
...

添加-车间.html你知道吗

...
  <div>
    <form method="post" action='' enctype='multipart/form-data'>
{% csrf_token %}
      {{ form | crispy }}
      <hr/>
        <div>
        {{ files | crispy }}
        </div>

      <input type="submit" class="btn btn-primary btn-md float-left" value="Save" />
    </form>
  </div>
...

Tags: instanceselfformtruedatareturnmodelsrequest
1条回答
网友
1楼 · 发布于 2024-04-20 07:39:21

您不应该重写post方法—它在幕后调用form_valid,因此它实际上不处理表单。另一件事是你的FileFormSet没有得到request.FILES——这就是为什么文件表单没有处理它。你知道吗

你知道吗视图.py地址:

class AddWorkshopView(LoginRequiredMixin, CreateView):

    model = Workshop
    form_class = AddWorkshopForm
    template_name = "modules/add-workshop.html"
    success_url = "/modules/workshop-list/"

    def get_context_data(self, **kwargs):
        data = super(AddWorkshopView, self).get_context_data(**kwargs)
        if self.request.POST:
            data['files'] = FileFormSet(self.request.POST, self.request.FILES)
        else:
            data['files'] = FileFormSet()
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        files = context['files']

        with transaction.atomic():
            form.instance.created_by = self.request.user
            form.instance.updated_by = self.request.user
            self.object = form.save()

            if files.is_valid():
                files.instance = self.object
                files.save()

        return super(AddWorkshopView, self).form_valid(form)

相关问题 更多 >