Ответ 1
Вам просто нужно две модели. Один для поста, а другой для изображений. Ваша модель изображения будет иметь внешний ключ к модели Post:
from django.db import models
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
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')
Вам необходимо создать форму для каждой модели, но они будут связаны друг с другом, например, когда пользователь заполняет форму сообщения, он должен заполнить форму с изображением, чтобы публикация была успешно опубликована, и мы сделаем это. что в представлениях, но пока ваша форма может выглядеть примерно так
from django import forms
from .models import Post, Images
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. Для этого нам понадобятся наборы форм django. Вы можете прочитать о наборах форм в документации Django, на которую я ссылаюсь :) Но вот как ваш взгляд должен выглядеть:
* Очень важен импорт
from django.shortcuts import render
from django.forms import modelformset_factory
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import HttpResponseRedirect
from .forms import ImageForm, PostForm
@login_required
def post(request):
ImageFormSet = modelformset_factory(Images,
form=ImageForm, extra=3)
#'extra' means the number of photos that you can upload ^
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:
#this helps to not crash if the user
#do not upload all the photos
if form:
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})
В представлении мы получаем обе наши формы, и представление проверит обе формы, если они действительны. Таким образом, пользователь должен заполнить форму и загрузить все изображения, которые в этом случае 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>