将多个文件字段添加到Django Modelform

发布于 2025-02-08 08:16:06 字数 1312 浏览 0 评论 0原文

我想创建一个允许多个图像上传的表单。我有一个listing模型,看起来像这样:

class Listing(models.Model):
    location = models.CharField("Address/Neighborhood", max_length=250)


class ListingImage(models.Model):
    listing = models.ForeignKey(
        Listing,
        related_name="images",
        on_delete=models.SET_NULL,
        null=True,
    )
    image = models.ImageField()

我正在使用 django-crispy-forms 在页面上创建表单,但我无法弄清楚如何将listing字段获取到页面上。

class ListingModelForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.helper = FormHelper()
        self.helper.layout = Layout(
            Fieldset(
                "Location",
                Div("location", css_class="col-md-12 col-lg-6")
            )
        )

        class Meta:
            model = Listing
            fields = "__all__"

这是我的观点:

class ListingCreateView(LoginRequiredMixin, CreateView):
    model = Listing
    form_class = ListingModelForm

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)

I'm wanting to create a form that allows multiple image uploads. I've got a Listing model that looks like this:

class Listing(models.Model):
    location = models.CharField("Address/Neighborhood", max_length=250)


class ListingImage(models.Model):
    listing = models.ForeignKey(
        Listing,
        related_name="images",
        on_delete=models.SET_NULL,
        null=True,
    )
    image = models.ImageField()

I'm using django-crispy-forms to create the form on the page but I cannot figure out how to get the listing field onto the page.

class ListingModelForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.helper = FormHelper()
        self.helper.layout = Layout(
            Fieldset(
                "Location",
                Div("location", css_class="col-md-12 col-lg-6")
            )
        )

        class Meta:
            model = Listing
            fields = "__all__"

And this is my view:

class ListingCreateView(LoginRequiredMixin, CreateView):
    model = Listing
    form_class = ListingModelForm

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super().form_valid(form)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

厌味 2025-02-15 08:16:06

如果我正确理解,您想拥有一个可以添加多个图像的字段,然后保存所有图像。如果我正确,那么这是您可以采用的一种方法。

在您设置的表单上添加一个额外的字段,以接受多个图像...例如:

class ListingModelForm(forms.ModelForm):
     # Extra field to collect multiple images
     listing_images = forms.ImageField(
          required=False,
          widget=forms.ClearableFileInput(attrs={'name': 'listing_images', 'id': 'listing_images', 'multiple': True})
     )

     # other portion of your form below...

您现在可以访问表单中的字段:{{form.listing_images}}},添加多个图像...

现在在该函数的post request中,您可以处理...您可以做:

if request.method == 'POST':
     form = ListingModelForm(data=request.POST, files=request.FILES)

     if form.is_valid():
          # listing = form.save(commit=False)
          # listing.location = 'blah blah'
          # listing.save()

          # or just use
          listing = form.save()

          # Looping over the list of images and create for each iteration
          for file in request.FILES.getlist('listing_images'):
              ListingImage.objects.create(listing=listing, image=file)

          # Also note that you could override the save method on the form to include the above forloop
          # if you don't want it out here...

假设您的image字段 listingingimage 有一条上传图像的路径,并已配置了您的Media_urlMedia_root设置...

更新

在知道您使用<<之前,请发布答案。代码>基于类的视图。

class ListingCreateView(LoginRequiredMixin, CreateView):
     model = Listing
     form_class = ListingModelForm

     def form_valid(self, form):
          # form.instance.user = self.request.user

          listing = form.save()  # Listing must be created first to use as the image reference

          for file in self.request.FILES.getlist('listing_images'):
               ListingImage.objects.create(listing=listing, image=file)

          return super(ListingCreateView, self).form_valid(form)
     
     # or using the post method
     def post(self, *args, *kwargs):
          form = ListingModelForm(data=request.POST, files=request.FILES)
          
          if form.is_valid():
               for file in self.request.FILES.getlist('listing_images'):
                    ListingImage.objects.create(listing=listing, image=file)
          
          return redirect('to a path...')
          

因此,您可以只使用上面在基于类的视图上突出显示的方法之一。

If I'm understanding correctly, you want to have a field where you'll be able to add multiple images and then save them all. If I'm correct, then here's an approach you could take.

Add an extra field on the form that you'll set to accept multiple images... for example:

class ListingModelForm(forms.ModelForm):
     # Extra field to collect multiple images
     listing_images = forms.ImageField(
          required=False,
          widget=forms.ClearableFileInput(attrs={'name': 'listing_images', 'id': 'listing_images', 'multiple': True})
     )

     # other portion of your form below...

You can now access the field in the form: {{ form.listing_images }}, adding multiple images...

Now within the function's post request you have handling that form... You can do:

if request.method == 'POST':
     form = ListingModelForm(data=request.POST, files=request.FILES)

     if form.is_valid():
          # listing = form.save(commit=False)
          # listing.location = 'blah blah'
          # listing.save()

          # or just use
          listing = form.save()

          # Looping over the list of images and create for each iteration
          for file in request.FILES.getlist('listing_images'):
              ListingImage.objects.create(listing=listing, image=file)

          # Also note that you could override the save method on the form to include the above forloop
          # if you don't want it out here...

Assuming that your image field on the ListingImage have a path to upload the images and have configured your MEDIA_URL and MEDIA_ROOT settings...

UPDATES

Posted an answer before knowing you were using the class-based view.

class ListingCreateView(LoginRequiredMixin, CreateView):
     model = Listing
     form_class = ListingModelForm

     def form_valid(self, form):
          # form.instance.user = self.request.user

          listing = form.save()  # Listing must be created first to use as the image reference

          for file in self.request.FILES.getlist('listing_images'):
               ListingImage.objects.create(listing=listing, image=file)

          return super(ListingCreateView, self).form_valid(form)
     
     # or using the post method
     def post(self, *args, *kwargs):
          form = ListingModelForm(data=request.POST, files=request.FILES)
          
          if form.is_valid():
               for file in self.request.FILES.getlist('listing_images'):
                    ListingImage.objects.create(listing=listing, image=file)
          
          return redirect('to a path...')
          

So you could just use one of the methods highlighted above on the class-based view.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文