Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

366
Vistas
Limite la cantidad de archivos que un usuario puede cargar

Tengo una carga de varios archivos y quiero limitar los usuarios a 3 cargas cada uno. Mi problema es que necesito saber cuántos archivos ya ha creado un user en la base de datos y cuántos están cargando actualmente (pueden cargar varios archivos a la vez y pueden cargar varias veces).

He intentado muchas cosas, incluyendo:

Creación de un validador (al validador se le pasó el archivo real que se agregó, no un model , por lo que no pude acceder al model para obtener su id para llamar if StudentUploadedFile.objects.filter(student_lesson_data=data.id).count() >= 4: ).

Haciendo la validación en clean(self): ( clean solo se pasó una instancia a la vez y la base de datos no se actualiza hasta que se limpian todos los archivos, por lo que pude contar los archivos que ya están en la base de datos pero no pude contar cuántos eran que se está cargando actualmente).

Usar un método pre-save (si la base de datos se actualiza entre cada archivo que se pasa a mi método pre-save , funcionaría, pero la base de datos solo se actualiza después de que todos los archivos que se cargan hayan pasado por mi método pre-save ).

Mi intento post-save :

 @receiver(pre_save, sender=StudentUploadedFile) def upload_file_pre_save(sender, instance, **kwargs): if StudentUploadedFile.objects.filter(student_lesson_data=instance.data.id).count() >= 4: raise ValidationError('Sorry, you cannot upload more than three files')

editar:

modelos.py

 class StudentUploadedFile(models.Model): student_lesson_data = models.ForeignKey(StudentLessonData, related_name='student_uploaded_file', on_delete=models.CASCADE) student_file = models.FileField(upload_to='module_student_files/', default=None)

vistas.py

 class StudentUploadView(View): def get(self, request): files_list = StudentUploadedFile.objects.all() return render(self.request, 'users/modules.html', {'student_files': files_list}) def post(self, request, *args, **kwargs): form = StudentUploadedFileForm(self.request.POST, self.request.FILES) form.instance.student_lesson_data_id = self.request.POST['student_lesson_data_id'] if form.is_valid(): uploaded_file = form.save() # pass uploaded_file data and username so new file can be added to students file list using ajax # lesson_id is used to output newly added file to corresponding newly_added_files div data = {'is_valid': True, 'username': request.user.username, 'file_id': uploaded_file.id, 'file_name': uploaded_file.filename(), 'lesson_id': uploaded_file.student_lesson_data_id, 'file_path': str(uploaded_file.student_file)} else: data = {'is_valid': False} return JsonResponse(data)

plantilla.py

 <form id='student_uploaded_file{{ item.instance.id }}'> {% csrf_token %} <a href="{% url 'download_student_uploaded_file' username=request.user.username file_path=item.instance.student_file %}" target='_blank'>{{ item.instance.filename }}</a> <a href="{% url 'delete_student_uploaded_file' username=request.user.username file_id=item.instance.id %}" class='delete' id='{{ item.instance.id }}'>Delete</a> </form>

js

 $(function () { // open file explorer window $(".js-upload-photos").on('click', function(){ // concatenates the id from the button pressed onto the end of fileupload class to call correct input element $("#fileupload" + this.id).click(); }); $('.fileupload_input').each(function() { $(this).fileupload({ dataType: 'json', done: function(e, data) { // process response from server // add newly added files to students uploaded files list if (data.result.is_valid) { $("#newly_added_files" + data.result.lesson_id).prepend("<form id='student_uploaded_file" + data.result.file_id + "'><a href='/student_hub/" + data.result.username + "/download_student_uploaded_file/" + data.result.file_path + "' target='_blank'>" + data.result.file_name + "</a><a href='/student_hub/" + data.result.username + "/delete_student_uploaded_file/" + data.result.file_id + "/' class='delete' id=" + data.result.file_id + ">Delete</a></form>") } } }); });

ACTUALIZAR: formularios.py

 class StudentUploadedFileForm(forms.ModelForm): student_file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

ver.py

 class StudentUploadView(View): model = StudentUploadedFile max_files_per_lesson = 3 def post(self, request, *args, **kwargs): lesson_data_id = request.POST['student_lesson_data_id'] current_files_count = self.model.objects.filter( student_lesson_data_id=lesson_data_id ).count() avail = self.max_files_per_lesson - current_files_count file_list = request.FILES.getlist('student_file') print(len(file_list)) if avail - len(file_list) < 0: return JsonResponse(data={ 'is_valid': False, 'reason': f'Too many files: you can only upload {avail}.' }) else: for f in file_list: print(f) data = {'test': True} return JsonResponse(data)

Gracias.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Entonces, la esencia es que está usando jQuery .each para cargar imágenes a través de AJAX. Cada solicitud POST a su vista de Django es una carga de un solo archivo, pero puede haber varias solicitudes al mismo tiempo.

Prueba esto:

formularios.py:

 class StudentUploadedFileForm(forms.ModelForm): class Meta: model = StudentUploadedFile fields = ('student_file', ) def __init__(self, *args, **kwargs): """Accept a 'student_lesson_data' parameter.""" self._student_lesson_data = kwargs.pop('student_lesson_data', None) super(StudentUploadedFileForm, self).__init__(*args, **kwargs) def clean(self): """ Ensure that the total number of student_uploaded_file instances that are linked to the student_lesson_data parameter are within limits.""" cleaned_data = super().clean() filecount = self._student_lesson_data.student_uploaded_file.count() if filecount >= 3: raise forms.ValidationError("Sorry, you cannot upload more than three files") return cleaned_data

vistas.py:

 class StudentUploadView(View): def get(self, request): # stuff ... def post(self, request, *args, **kwargs): sld_id = request.POST.get('student_lesson_data_id', None) student_lesson_data = StudentLessonData.objects.get(id=sld_id) form = StudentUploadedFileForm( request.POST, request.FILES, student_lesson_data=student_lesson_data ) if form.is_valid(): uploaded_file = form.save() # other stuff ...
over 4 years ago · Santiago Trujillo Denunciar

0

Supongo que puede usar la carga de archivos múltiples en Django aún no se ha filtrado a la comunidad. Extracto:

Si desea cargar varios archivos usando un campo de formulario, configure el atributo HTML múltiple del widget del campo:

 # forms.py from django import forms class FileFieldForm(forms.Form): file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

Su estructura de formulario y vista también es muy artificial, excluyendo campos de un formulario y luego configurando valores inyectados a través de un formulario HTML en la instancia del modelo. Sin embargo, con el código que se muestra, la instancia del modelo nunca existiría ya que el formulario no tiene un campo pk. De todos modos, para centrarnos en el problema que necesita solución...

En el formulario, request.FILES ahora es una matriz:

 class StudentUploadView(View): model = StudentUploadedFile max_files_per_lesson = 3 def post(request, *args, **kwargs): lesson_data_id = request.POST['student_lesson_data_id'] current_files_count = self.model.objects.filter( student_lesson_data_id=lesson_data_id ).count() avail = self.max_files_per_lesson - current_files_count file_list = request.FILES.get_list('student_file') if avail - len(file_list) < 0: return JsonResponse(data={ 'is_valid': False, 'reason': f'Too many files: you can only upload {avail}.' }) else: # create one new instance of self.model for each file ...

Abordar los comentarios: desde una perspectiva estética, se puede hacer mucho con el estilo ...

Sin embargo, la carga asíncrona (solicitudes POST separadas) complica mucho la validación y la experiencia del usuario:

  • El primer archivo puede terminar después del segundo, entonces, ¿cuál va a negar si el conteo es> 3?
  • La validación de front-end es pirateable, por lo que no puede confiar en ella, pero la validación de back-end se divide en varias solicitudes, que desde el punto de vista del usuario es una acción.
  • Pero con los archivos que llegan desordenados, algunos con éxito y otros con errores, ¿cómo va a proporcionar comentarios al usuario?
  • Si llegan 1, 3 y 4, pero al usuario le importa más 1, 2, 3, el usuario debe tomar varias medidas para corregir la situación.

Solicitud de una publicación:

  • No hay llegadas fuera de servicio
  • Puede utilizar un enfoque de "todo falla o todo tiene éxito", que es transparente para el usuario final y fácil de corregir.
  • Es probable que el orden de la matriz de archivos sea el orden preferido por el usuario, por lo que incluso si permite un éxito parcial, es probable que haga lo correcto.
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda