Как я могу загрузить файл на django, нажав на виджет?
У меня есть проект django, состоящий из различных форм с различными полями. Некоторые из них являются файловыми полями, где я загружаю файлы в медиа на основе этого класса. Я просто хочу сделать виджет для загрузки файлов, так что когда я редактирую в форме изменения, если файл был отправлен, я могу нажать на кнопку для загрузки. Каждый раз, когда я нажимаю на кнопку, которую я сделал, я получаю эту ошибку на консоли: "Не разрешено загружать локальный ресурс:", за которым следует мой локальный корень, что-то вроде file:///C:/proyectos/etc
Мой код слишком обширен, но я постараюсь показать вам большинство из них:
Models.py (этот класс предназначен для загрузки файловых полей)
class CustomStorage(FileSystemStorage):
# Almacenamiento nuevo en media
def __init__(self, *args, **kwargs):
super().__init__(location=os.path.join(settings.BASE_DIR, 'media','companies'), *args, **kwargs)
def submission_directory_path(instance, filename):
# Obtener el nombre comercial de la compañía y el ID del cliente
company_name = slugify(instance.client.company.comercial_name)
client_data = f"{instance.client.id}_{slugify(instance.client.name)}_{instance.type_submission.name}"
# Construir la ruta del directorio
directory_path = os.path.join(company_name, client_data)
# Devolver la ruta completa del archivo
return os.path.join(directory_path, filename)
Urls.py
urlpatterns = [
path('admin/', admin.site.urls),
#ENDPOINTS
path('client-details/<uuid:client_id>/', views.get_contact_details, name='client-details'),
path('panel/submission/<uuid:submission_id>/change/cancel', views.cancel_submission, name='cancel_submission'),
path('panel/submission/<uuid:submission_id>/change/no-apply', views.no_apply_submission, name='no_apply_submission'),
# Ir a pantalla de activación de cuenta
path('<str:name>/<str:uidb64>/<str:token>/', views.account_activation, name='account_activation'),
path('panel/submission/<uuid:submission_id>/download/<str:file_path>/', views.download_file, name='download_file'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
View.py
def download_file(request, file_path):
print("Ruta del archivo:", file_path)
file_path = os.path.join(settings.MEDIA_ROOT, file_path.replace("\\", "/"))
print("Ruta completa del archivo:", file_path)
if os.path.exists(file_path):
with open(file_path, 'rb') as file:
# response = HttpResponse(FileWrapper(file), content_type='application/pdf')
response = HttpResponse(FileWrapper(file), content_type=mimetypes.guess_type(file_path)[0])
response['Content-Disposition'] = f'attachment; filename="{os.path.basename(file_path)}"'
return response
else:
print("¡Archivo no encontrado!")
return HttpResponse('File not found', status=404)
forms.py
class DownloadFileWidget(forms.Widget):
template_name = 'download_widget.html' # Reemplaza con la ubicación real de tu plantilla
# def render(self, name, value, attrs=None, renderer=None):
# output = super().render(name, value, attrs, renderer)
# if value:
# file_path = value.url
# download_link = f'<a href="{file_path}" download>Descargar archivo</a>'
# output += mark_safe(download_link)
# return output
def render(self, name, value, attrs=None, renderer=None):
output = super().render(name, value, attrs, renderer)
if value:
file_path = value.path # Cambia de 'value.url' a 'value.path'
download_link = f'<a href="{file_path}" download>Descargar archivo</a>'
output += mark_safe(download_link)
return output
Download_widget.html
<!DOCTYPE html>
{% if widget.has_file %}
<form method="post" action="{% url 'download_file' file_path=widget.value %}" target="_blank">
{% csrf_token %}
<button type="submit">Descargar archivo</button>
</form>
{% endif %}```
Попробуйте этот метод здесь, он сработал в моем случае. Я использую VUE. Код ниже находится в моем компоненте Vue, а другой код ниже - в моем django view.py:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.4.8/vue.global.min.js">
buySheet(){
axios.post('/buySheet/' + this.sheet.id, { sheetId: this.sheet.id, sellerId: this.sheet.owner }, {
xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'X-CSRFTOKEN',
})
.then(response => {
// Handle the success response
console.log("Sheet saved successfully:", response.data);
window.location.href = `/download_concerto/${this.sheet.id}/`;
})
.catch(error => {
// Handle the error
console.error("Error saving sheet:", error);
});
},
</script>
def download_concerto(request, concerto_id):
concerto = get_object_or_404(Concerto, id=concerto_id)
# Here, you would include any logic to verify the user's right to access the file
# For example, check if the user has purchased the concerto
print(concerto.concerto_file_pdf, concerto.concerto_file_pdf.name)
return FileResponse(concerto.concerto_file_pdf, as_attachment=True, filename=concerto.concerto_file_pdf.name)