subir - formularios personalizados django
Necesita un ejemplo mÃnimo de carga de archivos Django (10)
Demo
Actualización de la respuesta de Akseli Palén . Ver el repositorio de github , trabaja con Django 2.
Un ejemplo mínimo de carga de archivos Django
1. Crea un proyecto django.
Ejecutar startproject ::
$ django-admin.py startproject sample
ahora se crea una carpeta ( muestra ) ::
sample/
manage.py
sample/
__init__.py
settings.py
urls.py
wsgi.py
2. crear una aplicación
Crear una aplicación ::
$ cd sample
$ python manage.py startapp uploader
Ahora se crea una carpeta ( uploader
) con estos archivos:
uploader/
__init__.py
admin.py
app.py
models.py
tests.py
views.py
migrations/
__init__.py
3. Actualizar settings.py
En sample/settings.py
agregue ''uploader.apps.UploaderConfig''
a INSTALLED_APPS
y agregue MEDIA_ROOT
y MEDIA_URL
, es decir:
INSTALLED_APPS = [
...<other apps>...
''uploader.apps.UploaderConfig'',
]
MEDIA_ROOT = os.path.join(BASE_DIR, ''media'')
MEDIA_URL = ''/media/''
4. Actualizar urls.py
en sample/urls.py
add ::
...<other imports>...
from django.conf import settings
from django.conf.urls.static import static
from uploader import views as uploader_views
urlpatterns = [
...<other url patterns>...
path('''', uploader_views.home, name=''imageupload''),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
5. Actualizar models.py
actualizar uploader/models.py
::
from django.db import models
from django.forms import ModelForm
class Upload(models.Model):
pic = models.FileField(upload_to="images/")
upload_date=models.DateTimeField(auto_now_add =True)
# FileUpload form class.
class UploadForm(ModelForm):
class Meta:
model = Upload
fields = (''pic'',)
6. Actualizar views.py
actualizar uploader/views.py
::
from django.shortcuts import render
from uploader.models import UploadForm,Upload
from django.http import HttpResponseRedirect
from django.urls import reverse
# Create your views here.
def home(request):
if request.method=="POST":
img = UploadForm(request.POST, request.FILES)
if img.is_valid():
img.save()
return HttpResponseRedirect(reverse(''imageupload''))
else:
img=UploadForm()
images=Upload.objects.all().order_by(''-upload_date'')
return render(request,''home.html'',{''form'':img,''images'':images})
7. crear plantillas
Cree plantillas de carpeta en la carpeta uploader , luego cree un archivo home.html , es decir, sample/uploader/templates/home.html
::
<div style="padding:40px;margin:40px;border:1px solid #ccc">
<h1>picture</h1>
<form action="#" method="post" enctype="multipart/form-data">
{% csrf_token %} {{form}}
<input type="submit" value="Upload" />
</form>
{% for img in images %}
{{forloop.counter}}.<a href="{{ img.pic.url }}">{{ img.pic.name }}</a>
({{img.upload_date}})<hr />
{% endfor %}
</div>
8. sincronizar la base de datos
Sincronizar la base de datos y el servidor de ejecución:
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver
Visita http://localhost.com:8000
Como novato en Django, tengo dificultades para realizar una aplicación de carga en Django 1.3. No he podido encontrar ningún ejemplo / fragmento actualizado. ¿Puede alguien publicar un código de ejemplo mínimo pero completo (Modelo, Vista, Plantilla) para hacerlo?
Aquí le puede ayudar: crear un campo de archivo en su models.py
Para subir el archivo (en su admin.py):
def save_model(self, request, obj, form, change):
url = "http://img.youtube.com/vi/%s/hqdefault.jpg" %(obj.video)
url = str(url)
if url:
temp_img = NamedTemporaryFile(delete=True)
temp_img.write(urllib2.urlopen(url).read())
temp_img.flush()
filename_img = urlparse(url).path.split(''/'')[-1]
obj.image.save(filename_img,File(temp_img)
y usa ese campo en tu plantilla también.
Debo decir que encuentro la documentación en django confusa. También para el ejemplo más simple, ¿por qué se mencionan los formularios? El ejemplo que tengo para trabajar en views.py es:
for key, file in request.FILES.items():
path = file.name
dest = open(path, ''w'')
if file.multiple_chunks:
for c in file.chunks():
dest.write(c)
else:
dest.write(file.read())
dest.close()
El archivo html se parece al código de abajo, aunque este ejemplo solo carga un archivo y el código para guardar los archivos se encarga de muchos:
<form action="/upload_file/" method="post" enctype="multipart/form-data">{% csrf_token %}
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
Estos ejemplos no son mi código, se han obtenido de otros dos ejemplos que encontré. Soy un principiante relativo de django, por lo que es muy probable que me esté perdiendo algún punto clave.
En general, cuando intenta "obtener un ejemplo práctico", es mejor "comenzar a escribir código". No hay ningún código aquí para ayudarlo, por lo que responder a la pregunta es mucho más fácil para nosotros.
Si desea capturar un archivo, necesita algo como esto en un archivo html en algún lugar:
<form method="post" enctype="multipart/form-data">
<input type="file" name="myfile" />
<input type="submit" name="submit" value="Upload" />
</form>
Eso le dará el botón de navegación, un botón de carga para iniciar la acción (enviar el formulario) y anotar el enctype para que Django sepa que debe realizar la request.FILES
. request.FILES
En una vista en algún lugar puede acceder al archivo con
def myview(request):
request.FILES[''myfile''] # this is my file
Hay una gran cantidad de información en los documentos de carga de archivos
Le recomiendo que lea la página detenidamente y comience a escribir el código ; luego vuelva con ejemplos y acumule trazas cuando no funcione.
Extendiendo en el ejemplo de Henry :
import tempfile
import shutil
FILE_UPLOAD_DIR = ''/home/imran/uploads''
def handle_uploaded_file(source):
fd, filepath = tempfile.mkstemp(prefix=source.name, dir=FILE_UPLOAD_DIR)
with open(filepath, ''wb'') as dest:
shutil.copyfileobj(source, dest)
return filepath
Puede llamar a esta función handle_uploaded_file
desde su vista con el objeto de archivo cargado. Esto guardará el archivo con un nombre único (prefijado con el nombre de archivo del archivo original cargado) en el sistema de archivos y devolverá la ruta completa del archivo guardado. Puede guardar la ruta en la base de datos y hacer algo con el archivo más adelante.
Few, la documentación de Django realmente no tiene buen ejemplo sobre esto. Pasé más de 2 horas para desenterrar todas las piezas para entender cómo funciona esto. Con ese conocimiento, implementé un proyecto que hace posible subir archivos y mostrarlos como una lista. Para descargar el código fuente del proyecto, visite https://github.com/axelpale/minimal-django-file-upload-example o clone:
> git clone https://github.com/axelpale/minimal-django-file-upload-example.git
Actualización 2013-01-30: La fuente en GitHub también tiene implementación para Django 1.4 además de 1.3. Aunque hay pocos cambios, el siguiente tutorial también es útil para 1.4.
Actualización 2013-05-10: Implementación para Django 1.5 en GitHub. Cambios menores en la redirección en urls.py y el uso de la etiqueta de la plantilla url en list.html. Gracias a hubert3 por el esfuerzo.
Actualización 2013-12-07: Django 1.6 soportado en GitHub. Una importación cambió en myapp / urls.py. Gracias a Arthedian .
Actualización 2015-03-17: Django 1.7 admitido en GitHub, gracias a aronysidoro .
Actualización 2015-09-04: Django 1.8 admitido en GitHub, gracias a nerogit .
Actualización 2016-07-03: Django 1.9 admitido en GitHub, gracias a daavve y nerogit
Árbol de proyectos
Un proyecto básico de Django 1.3 con una sola aplicación y medio / directorio para subir archivos.
minimal-django-file-upload-example/
src/
myproject/
database/
sqlite.db
media/
myapp/
templates/
myapp/
list.html
forms.py
models.py
urls.py
views.py
__init__.py
manage.py
settings.py
urls.py
1. Configuraciones: myproject / settings.py
Para cargar y servir archivos, debe especificar dónde almacena Django los archivos cargados y de qué URL les sirve Django. MEDIA_ROOT y MEDIA_URL están en settings.py por defecto pero están vacíos. Vea las primeras líneas en Django Managing Files para más detalles. Recuerde también configurar la base de datos y agregar myapp a INSTALLED_APPS
...
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
...
DATABASES = {
''default'': {
''ENGINE'': ''django.db.backends.sqlite3'',
''NAME'': os.path.join(BASE_DIR, ''database.sqlite3''),
''USER'': '''',
''PASSWORD'': '''',
''HOST'': '''',
''PORT'': '''',
}
}
...
MEDIA_ROOT = os.path.join(BASE_DIR, ''media'')
MEDIA_URL = ''/media/''
...
INSTALLED_APPS = (
...
''myapp'',
)
2. Modelo: myproject / myapp / models.py
A continuación necesitas un modelo con un FileField. Este campo particular almacena archivos, por ejemplo, a media / documents / 2011/12/24 / basado en la fecha actual y MEDIA_ROOT. Ver referencia FileField .
# -*- coding: utf-8 -*-
from django.db import models
class Document(models.Model):
docfile = models.FileField(upload_to=''documents/%Y/%m/%d'')
3. Forma: myproject / myapp / forms.py
Para manejar bien subir, necesita un formulario. Esta forma tiene un solo campo pero eso es suficiente. Vea la referencia de formulario FileField para más detalles.
# -*- coding: utf-8 -*-
from django import forms
class DocumentForm(forms.Form):
docfile = forms.FileField(
label=''Select a file'',
help_text=''max. 42 megabytes''
)
4. Ver: myproject / myapp / views.py
Una vista donde pasa toda la magia. Preste atención a cómo se manejan las request.FILES
. Para mí, fue muy difícil detectar el hecho de que la request.FILES[''docfile'']
se pueden guardar en modelos. Campo de campo de esa manera. Save () del modelo maneja el almacenamiento del archivo en el sistema de archivos automáticamente.
# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from myproject.myapp.models import Document
from myproject.myapp.forms import DocumentForm
def list(request):
# Handle file upload
if request.method == ''POST'':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES[''docfile''])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse(''myapp.views.list''))
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
''myapp/list.html'',
{''documents'': documents, ''form'': form},
context_instance=RequestContext(request)
)
5. URL del proyecto: myproject / urls.py
Django no sirve MEDIA_ROOT por defecto. Eso sería peligroso en el entorno de producción. Pero en la etapa de desarrollo, podríamos acortar. Presta atención a la última línea. Esa línea le permite a Django servir archivos desde MEDIA_URL. Esto funciona solo en la etapa de desarrollo.
Consulte la referencia django.conf.urls.static.static para más detalles. Véase también esta discusión sobre el servicio de archivos multimedia .
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('''',
(r''^'', include(''myapp.urls'')),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
6. URL de la aplicación: myproject / myapp / urls.py
Para hacer que la vista sea accesible, debe especificar las URL para ella. Nada especial aquí.
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
urlpatterns = patterns(''myapp.views'',
url(r''^list/$'', ''list'', name=''list''),
)
7. Plantilla: myproject / myapp / templates / myapp / list.html
La última parte: plantilla para la lista y el formulario de carga debajo de ella. El formulario debe tener enctype-attribute configurado en "multipart / form-data" y el método configurado en "post" para hacer posible la carga a Django. Consulte la documentación de Subidas de archivos para más detalles.
El FileField tiene muchos atributos que se pueden usar en las plantillas. Por ejemplo, {{document.docfile.url}} y {{document.docfile.name}} como en la plantilla. Para obtener más información sobre esto, consulte el artículo Uso de archivos en modelos y la documentación del objeto Archivo .
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Minimal Django File Upload Example</title>
</head>
<body>
<!-- List of uploaded documents -->
{% if documents %}
<ul>
{% for document in documents %}
<li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No documents.</p>
{% endif %}
<!-- Upload form. Note enctype attribute! -->
<form action="{% url ''list'' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload" /></p>
</form>
</body>
</html>
8. Inicializar
Simplemente ejecute syncdb y runserver.
> cd myproject
> python manage.py syncdb
> python manage.py runserver
Resultados
Finalmente, todo está listo. En el entorno de desarrollo de Django predeterminado, la lista de documentos cargados se puede ver en localhost:8000/list/
. Hoy los archivos se cargan en / path / to / myproject / media / documents / 2011/12/17 / y se pueden abrir desde la lista.
Espero que esta respuesta ayude a alguien tanto como me hubiera ayudado.
Me enfrenté al problema similar, y resuelto por el sitio de administración de django.
# models
class Document(models.Model):
docfile = models.FileField(upload_to=''documents/Temp/%Y/%m/%d'')
def doc_name(self):
return self.docfile.name.split(''/'')[-1] # only the name, not full path
# admin
from myapp.models import Document
class DocumentAdmin(admin.ModelAdmin):
list_display = (''doc_name'',)
admin.site.register(Document, DocumentAdmin)
No estoy seguro de si hay alguna desventaja en este enfoque pero aún más mínimo, en views.py:
entry = form.save()
# save uploaded file
if request.FILES[''myfile'']:
entry.myfile.save(request.FILES[''myfile'']._name, request.FILES[''myfile''], True)
Puede consultar ejemplos de servidores en Fine Uploader, que tiene la versión de django. https://github.com/FineUploader/server-examples/tree/master/python/django-fine-uploader
Es muy elegante y lo más importante de todo, ofrece js lib destacado. La plantilla no está incluida en los ejemplos de servidor, pero puede encontrar una demostración en su sitio web. Cargador fino: http://fineuploader.com/demos.html
django-fine-uploader
vistas.py
UploadView envía las solicitudes de publicación y eliminación a los controladores respectivos.
class UploadView(View):
@csrf_exempt
def dispatch(self, *args, **kwargs):
return super(UploadView, self).dispatch(*args, **kwargs)
def post(self, request, *args, **kwargs):
"""A POST request. Validate the form and then handle the upload
based ont the POSTed data. Does not handle extra parameters yet.
"""
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_upload(request.FILES[''qqfile''], form.cleaned_data)
return make_response(content=json.dumps({ ''success'': True }))
else:
return make_response(status=400,
content=json.dumps({
''success'': False,
''error'': ''%s'' % repr(form.errors)
}))
def delete(self, request, *args, **kwargs):
"""A DELETE request. If found, deletes a file with the corresponding
UUID from the server''s filesystem.
"""
qquuid = kwargs.get(''qquuid'', '''')
if qquuid:
try:
handle_deleted_file(qquuid)
return make_response(content=json.dumps({ ''success'': True }))
except Exception, e:
return make_response(status=400,
content=json.dumps({
''success'': False,
''error'': ''%s'' % repr(e)
}))
return make_response(status=404,
content=json.dumps({
''success'': False,
''error'': ''File not present''
}))
forms.py
class UploadFileForm(forms.Form):
""" This form represents a basic request from Fine Uploader.
The required fields will **always** be sent, the other fields are optional
based on your setup.
Edit this if you want to add custom parameters in the body of the POST
request.
"""
qqfile = forms.FileField()
qquuid = forms.CharField()
qqfilename = forms.CharField()
qqpartindex = forms.IntegerField(required=False)
qqchunksize = forms.IntegerField(required=False)
qqpartbyteoffset = forms.IntegerField(required=False)
qqtotalfilesize = forms.IntegerField(required=False)
qqtotalparts = forms.IntegerField(required=False)
Yo también tenía el requisito similar. La mayoría de los ejemplos en la red solicitan crear modelos y crear formularios que no quisiera usar. Aquí está mi código final.
if request.method == ''POST'':
file1 = request.FILES[''file'']
contentOfFile = file1.read()
if file1:
return render(request, ''blogapp/Statistics.html'', {''file'': file1, ''contentOfFile'': contentOfFile})
Y en HTML para subir escribí:
{% block content %}
<h1>File content</h1>
<form action="{% url ''blogapp:uploadComplete''%}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input id="uploadbutton" type="file" value="Browse" name="file" accept="text/csv" />
<input type="submit" value="Upload" />
</form>
{% endblock %}
A continuación se muestra el HTML que muestra el contenido del archivo:
{% block content %}
<h3>File uploaded successfully</h3>
{{file.name}}
</br>content = {{contentOfFile}}
{% endblock %}