Nuestro equipo de redactores ha estado mucho tiempo buscando para dar resolución a tus dudas, te regalamos la respuestas por esto deseamos resultarte de mucha apoyo.
Solución:
Solo necesitarás dos modelos. Uno para el Post y el otro para las Imágenes. Su modelo de imagen tendría una clave extranjera para el modelo de publicación:
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')
Debe crear un formulario para cada modelo, pero estarán relacionados entre sí, como cuando el usuario está completando la publicación del formulario, también debe completar el formulario de imagen para que la publicación se publique con éxito, y nosotros lo haremos. eso en las vistas, pero por ahora su formulario puede verse así
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', )
Ahora bien, esta es la parte más importante de todo, las vistas, porque aquí es donde sucede la carga de múltiples imágenes a una sola magia. Para que podamos cargar varias imágenes a la vez, necesitamos varios campos de imagen, ¿verdad? Ahí es donde te enamoras de los conjuntos de formularios de Django. Necesitaremos conjuntos de formularios de django para que esto suceda, puede leer sobre conjuntos de formularios en la documentación de Django, que he vinculado 🙂 Pero así es como debería verse su vista:
* Muy importantes las importaciones
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
from .models import Images
@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()
# use django messages framework
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)
En la vista, estamos obteniendo nuestros dos formularios, y verificará ambos formularios si son válidos o no. De esa forma, el usuario debe llenar el formulario Y subir todas las imágenes que, en este caso, son 3 extra=3
. Solo entonces se creará la publicación con éxito.
Su plantilla debería verse así entonces:
Solución paso-a-paso => Incluso, yo también estaba atascado. Así que así es como yo exitosamente hacer.
Finally
, implementando el siguiente código, Lo logré
- Modelo de 1 nota con muchas imágenes
- Varias cargas(en el Mismo tiempo, con mismo botón Elegir archivo, y todos guardan juntos como en Carga de archivos de Gmail)
Aquí está mi modelo de imagen y nota (o ver el código completo)
class Note(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
title = models.CharField(max_length=30)
text = models.TextField(null=True,blank=True)
created_date = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
class Images(models.Model):
note = models.ForeignKey(Note,on_delete=models.CASCADE)
image = models.ImageField(upload_to=user_directory_path,null=True,blank=True)
Aquí está mi formulario (Enlace del documento en carga múltiple) – (o ver el código completo)
class NoteForm(forms.ModelForm):
class Meta:
model = Note
fields = ['title','text'] #make sure to mention field here, if nothing is mentioned then all will be required.
class NoteFullForm(NoteForm): #extending form
images = forms.FileField(widget=forms.ClearableFileInput(attrs='multiple': True))
class Meta(NoteForm.Meta):
fields = NoteForm.Meta.fields + ['images',]
Aquí está mi archivo Ver- (o ver código completo)
def addNoteView(request):
if request.method == "POST":
#images will be in request.FILES
form = NoteFullForm(request.POST or None, request.FILES or None)
files = request.FILES.getlist('images')
if form.is_valid():
user = request.user
title = form.cleaned_data['title']
text = form.cleaned_data['text']
note_obj = Note.objects.create(user=user,title=title,text=text) #create will create as well as save too in db.
for f in files:
Images.objects.create(note=note_obj,image=f)
else:
print("Form invalid")
Y, finalmente mi archivo Html (asegúrese de vincular los archivos como se indica en los documentos) – (o consulte el código completo)