как загрузить несколько изображений в блог в django

Я пытаюсь разрешить каждому пользователю загружать несколько фотографий в один блог. Я пытаюсь найти лучший способ сделать это в течение нескольких дней. Какова наилучшая практика для этого?

из того, что я прочитал, я должен сделать отдельную модель изображения из модели блога и использовать внешний ключ. Это правда? Тогда есть вопрос о том, как позволить им загружать несколько фотографий одновременно. Я прав, предполагая, что должен использовать что-то вроде drop зона?

любые советы по передовой практике для хранения фотографий также приветствуются. Я посмотрел на Amazon s3 и cloudinary. Я хочу создать что-то масштабируемое.

любая помощь была бы очень признательна!

2 ответов


вам просто нужны две модели. Один для поста, а другой для изображений. Ваша модель изображения будет иметь внешний ключ к модели Post:

class Post(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField(max_length=128)
    body = models.CharField(max_length=400)

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)
    image = models.ImageField(upload_to=get_image_filename,
                              verbose_name='Image')

вам нужно создать форму для каждой модели, но они будут связаны друг с другом, так как, когда пользователь заполняет сообщение формы, он должен заполнить форму изображения, чтобы сообщение было успешно опубликовано, и мы сделаем это в представлениях, но пока ваша форма может выглядеть примерно так

class PostForm(forms.ModelForm):
    title = forms.CharField(max_length=128)
    body = forms.CharField(max_length=245, label="Item Description.")

    class Meta:
        model = Post
        fields = ('title', 'body', )


class ImageForm(forms.ModelForm):
    image = forms.ImageField(label='Image')    
    class Meta:
        model = Images
        fields = ('image', )

теперь это самая важная часть всего, представления, потому что здесь происходит загрузка нескольких изображений в одну магию. Для того, чтобы мы могли загружать несколько изображений одновременно, нам нужно несколько полей изображения, верно? Вот где вы влюбляетесь в Django formsets. Чтобы это произошло, вы можете прочитать о formsets в документации Django, которую я связал :) но вот как должно выглядеть ваше представление например:

@login_required
def post(request):

    ImageFormSet = modelformset_factory(Images,
                                        form=ImageForm, extra=3)

    if request.method == 'POST':

        postForm = PostForm(request.POST)
        formset = ImageFormSet(request.POST, request.FILES,
                               queryset=Images.objects.none())


        if postForm.is_valid() and formset.is_valid():
            post_form = postForm.save(commit=False)
            post_form.user = request.user
            post_form.save()

            for form in formset.cleaned_data:
                image = form['image']
                photo = Images(post=post_form, image=image)
                photo.save()
            messages.success(request,
                             "Yeeew, check it out on the home page!")
            return HttpResponseRedirect("/")
        else:
            print postForm.errors, formset.errors
    else:
        postForm = PostForm()
        formset = ImageFormSet(queryset=Images.objects.none())
    return render(request, 'index.html',
                  {'postForm': postForm, 'formset': formset},
                  context_instance=RequestContext(request))

в представлении мы получаем обе наши формы, и представление будет проверять обе формы, если они действительны. Таким образом, пользователь должен заполнить форму и загрузить все изображения, которые в этом случае 3 extra=3. Только тогда сообщение будет успешно создано.

вы шаблон должен выглядеть вот так:

<form id="post_form" method="post" action="" enctype="multipart/form-data">

    {% csrf_token %}
    {% for hidden in postForm.hidden_fields %}
        {{ hidden }}
    {% endfor %}

    {% for field in postForm %}
        {{ field }} <br />
    {% endfor %}

    {{ formset.management_form }}
    {% for form in formset %}
        {{ form }}
    {% endfor %}


    <input type="submit" name="submit" value="Submit" />
</form>

Если у вас есть некоторые входные данные name=image1 name=image2 name=image3 и т. д. В вашем шаблоне попробуйте это

for i in xrange(1,4):
        if ('image'+str(i)) in request.FILES:
            image = request.FILES.get('image'+str(i), None)
            if image.content_type == 'image/jpeg' 
                image._set_name(str(description.id)+'_image'+str(i)+'.jpg')
                photo = Images(description=description, image=image)
                photo.save()