Estoy tratando de crear un formulario simple para compartir publicaciones como este.
Estoy usando formset para cargar imágenes. Pero esto me da entrada múltiple como puede ver. Además, cada entrada puede elegir una sola imagen. Pero estoy tratando de cargar varias imágenes con una sola entrada.
vistas.py
def share(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 = postForm.save(commit=False) post.author = request.user post.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, image=image) photo.save() return redirect("index") else: print(postForm.errors, formset.errors) else: postForm = PostForm() formset = ImageFormSet(queryset=Images.objects.none()) return render(request, "share.html", {"postForm": postForm, 'formset': formset})compartir.html
<form method="POST" id="post-form" class="post-form js-post-form" enctype="multipart/form-data"> {% csrf_token %} {{ formset.management_form }} {% for form in formset %} {{ form }} {% endfor %} </form>si lo necesita, formularios.py
class PostForm(forms.ModelForm): class Meta: model = Post fields = ["title", "content"] def __init__(self, *args, **kwargs): super(PostForm, self).__init__(*args, **kwargs) self.fields['title'].widget.attrs.update({'class': 'input'}) self.fields['content'].widget.attrs.update({'class': 'textarea'}) class ImageForm(forms.ModelForm): image = forms.ImageField(label='Image') class Meta: model = Images fields = ('image', ) def __init__(self, *args, **kwargs): self.fields['image'].widget.attrs.update( {'class': 'fileinput', 'multiple': True})modelos.py
from django.db import models from django.contrib.auth.models import User from django.template.defaultfilters import slugify class Post(models.Model): # on_delete ile, bu kullanıcı silindiğinde bu kullanıcıya ait tüm postlar da silinecek. author = models.ForeignKey( "auth.User", on_delete=models.CASCADE, verbose_name="Yazar") title = models.CharField(max_length=150, verbose_name="Başlık") content = models.TextField(verbose_name="İçerik") # auto_now_add = True ile veritabanına eklendiği tarihi otomatik alacak created_date = models.DateTimeField(auto_now_add=True) # admin panelinde Post Object 1 yazması yerine başlığı yazsın istersek... def __str__(self): return self.title 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, on_delete=models.DO_NOTHING, default=None) image = models.ImageField(upload_to=get_image_filename, verbose_name='Image', default="images/default_game_img.png")Si necesita uno archivado para la carga de múltiples imágenes, intente esto:
vistas.py
from .forms import PostForm from .models import Post, Images def share(request): form = PostForm() if request.method == 'POST': post = Post() post.title = request.POST['title'] post.content = request.POST['content'] post.author = request.user post.save() for image in request.FILES.getlist('images'): image_obj = Image() image_obj.post_id = post.id image_obj.image = image image_obj.save() return render(request, 'share.html', {'form': form})formularios.py
from django import forms class PostForm(forms.Form): title = forms.CharField(label='', widget=forms.TextInput(attrs={ 'class': 'input', } )) content = forms.CharField(label='', widget=forms.Textarea(attrs={ 'class': 'textarea', } )) images = forms.ImageField(widget=forms.ClearableFileInput(attrs={'multiple': True}))compartir.html
<form method="POST" id="post-form" class="post-form js-post-form" enctype="multipart/form-data"> {% csrf_token %} {% for elem in form %} {{ elem }} {% endfor %} </form>Creo que estás pensando demasiado en la implementación, deberías probar lib como django-multiupload
Y puede encontrar una implementación válida para la carga de imágenes múltiples a través de este enlace
https://stackoverflow.com/a/44075555/10798048
Espero que esto facilite su implementación y resuelva su problema. Corrígeme si no te funciona.