简体   繁体   中英

How do I access images uploaded through a formset in Django?

I cannot seem to find a way to iterate through the files uploaded by the formset, although the files are uploaded as the code indicates.

When I load the page it shows 1-3 "img src=(unkown)" tags. It shows 3 when I upload 2 images and 1 when I upload 1 image.

Template view-post:

{% block body %}
<div class="container">
<div class="col-md-8">
    <p>
        <h1>{{ post.title }}</h1>
        <h4>{{ post.body }}</h4>
        <p>
            Posted by {{ post.user }} on {{ post.created_date }}
            {% if not post.created_date == post.updated_date %}
            and updated on {{ post.updated_date }}
            {% endif %}
        </p>
    </p>
    {% for img in images %}
    <img src="{{ img.url }}" width=360>
    {{ img.url }}
    <br>
    {% endfor %}
</div>
<div class="col-4-md">
    {% if post.cover_image %}
    <img src="{{ post.cover_image.url }}" width=240>
    {% endif %}
</div>
</div>
{% endblock %}

Here I use filter, not get, so it should give me a list of the images connected via foreignkey to the right post. The post here is displayed as it should be, along with the internal cover image and text in the post.

View view-post:

class ViewPost(TemplateView):
    template_name = 'posts/view_post.html'
    context_object_name = 'view_post'

def get(self, request, pk):
    post = Post.objects.get(pk=pk)
    images = Images.objects.filter(post=post)
    args = {'post': post, 'images': images}
    return render(request, self.template_name, args)

Template make-post:

{% block body %}
<div class="container">
<div class="col-md-8">
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.as_p }}
        {{ form.errors }}
        {% csrf_token %}
        {{ formset.management_form }}
        {% for form in formset %}
            {{ form }}
        {% endfor %}
    <button type="submit">Submit</button>
    </form>
</div>
</div>
{% endblock %}

View make-post:

class MakePost(DetailView):

    template_name = 'posts/make_post.html'
    ImageFormSet = modelformset_factory(Images, form=ImageForm, extra=3)

def get(self, request):
    form = PostForm()
    formset = self.ImageFormSet(queryset=Images.objects.none())
    args = {'form': form, 'formset': formset}
    return render(request, self.template_name, args)

def post(self, request):
    form = PostForm(request.POST, request.FILES)
    formset = self.ImageFormSet(request.POST, request.FILES,
                           queryset=Images.objects.none())
    if form.is_valid() and formset.is_valid():
        post = form.save(commit=False)
        post.user = request.user
        post.cover_image = form.cleaned_data['cover_image']
        post.title = form.cleaned_data['title']
        post.body = form.cleaned_data['body']
        post.save()

        for imgform in formset:
            image = imgform.cleaned_data.get('image')
            photo = Images(post=post, post_image=image)
            photo.save()
        return redirect('home_space:home')
    else:
        return redirect('home_space:home')

Function to name files and image Model:

def get_image_filename(instance, filename):
    title = instance.post.title
    slug = slugify(title)
    return "post_images/%s-%s" % (slug, filename)

class Images(models.Model):
    post = models.ForeignKey(Post, default=None, on_delete=models.CASCADE)
    post_image = models.ImageField(upload_to=get_image_filename,
                          verbose_name='Image')

In your template, you are accessing url of Images model instance. But, the url property is in ImageField class instance. Use img.post_image.url .

Example :

{% for img in images %}
    <img src="{{ img.post_image.url }}" width=360>
    {{ img.post_image.url }}
    <br>
{% endfor %}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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