2020-04-07 Created: windows10 / Python-3.8.2-amd64 / Django-3.0.4
How to upload files in generic class view in Django There is not much information in Japanese. Therefore, it took a long time. I will write an article so that I will not forget it. This article is for those who want a quick understanding of the principles of file uploads.
If you're new to Django, click here. Practical tutorial on Django in 10 minutes
The project name is mysite and the application name is fileupload. Create a folder media in mysite / and use it as a file storage location.
The file layout up to this point is as follows.
mysite/
mysite/
__pycashe__/ <-do not worry about
setting.py, urls.py etc.*.5 py
fileupload/
migrations/ <-do not worry about
models.py, views.py etc.*.6 py
media/ <-Where to save the uploaded file
manage.py <-For project management
Register the application fileupload in your Django project. Therefore, add it to INSTALLED_APPS in settings.py.
mysite/mysite/settings.py
INSTALLED_APPS = [
'fileupload.apps.FileuploadConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Also register a directory for uploading files. For that, add two lines to settings.py.
mysite/mysite/settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
Added to urls.py to register url.
mysite/mysite/urls.py
from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('fileupload/', include('fileupload.urls')),
path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Create a model Fileupload. There are two fields, the title of the file and the file itself. The file is saved in a folder named media / uploads / year / month / day. Assuming that you are uploading photos, the extension is only jpg.
mysite/fileupload/models.py
from django.db import models
from django.core.validators import FileExtensionValidator
class Fileupload(models.Model):
titlefield = models.CharField(max_length = 200, null = True)
filefield = models.FileField(
upload_to = 'uploads/%Y/%m/%d/',
verbose_name = 'attached file',
validators=[FileExtensionValidator(['jpg', ])],
null = True
)
Create a view.
After all, it's easy to use Django's generic class view.
The generic class view has default variable names, file names, etc.
You cannot use it without knowing (for example, fileupload_object_name
or template_name
).
That's why I explicitly gave it a descriptive name instead of the default name.
mysite/fileupload/views.py
from django.views import generic
from .models import Fileupload
class FileuploadListView(generic.ListView):
model = Fileupload
context_object_name = 'fileupload_context_list'
class FileuploadCreateView(generic.CreateView):
model = Fileupload
fields = ['titlefield', 'filefield']
success_url = '/fileupload'
template_name = 'fileupload/fileupload_create.html'
class FileuploadDetailView(generic.DetailView):
model = Fileupload
template_name = 'fileupload/fileupload_detail.html'
context_object_name = 'fileupload_context'
class FileuploadUpdateView(generic.UpdateView):
model = Fileupload
fields = ['titlefield', 'filefield']
success_url = '/fileupload'
template_name = 'fileupload/fileupload_update.html'
class FileuploadDeleteView(generic.DeleteView):
model = Fileupload
success_url = '/fileupload'
template_name = 'fileupload/fileupload_delete.html'
Register the view in the url. Create a new file fileupload / urls.py. Register the created view.
mysite/fileupload/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.FileuploadListView.as_view()),
path('index', views.FileuploadListView.as_view(),
name = 'site_index'),
path('create', views.FileuploadCreateView.as_view(),
name = 'site_create'),
path('detail/<int:pk>', views.FileuploadDetailView.as_view(),
name = 'site_detail'),
path('update/<int:pk>', views.FileuploadUpdateView.as_view(),
name = 'site_update'),
path('delete/<int:pk>', views.FileuploadDeleteView.as_view(),
name = 'site_delete'),
]
Create an html file for the template in fileupload / templates / fileupload /
.
Corresponds to each view.
mysite/fileupload/templates/fileupload/fileupload_list.html
<h1>List files</h1>
{% if fileupload_context_list %}
<table>
{% for temp in fileupload_context_list %}
<tr>
<td><a href = "{% url 'site_detail' temp.pk %}"> {{ temp.titlefield }}</a></td>
<td>{{ temp.filefield }}</td>
<td><a href = "{% url 'site_update' temp.pk %}">Edit</a></td>
<td><a href = "{% url 'site_delete' temp.pk %}">Delete</a></td>
</tr>
{% endfor %}
</table>
{% else %}
<p>No file available.</p>
{% endif %}
<p><a href = "{% url 'site_create' %}">Upload new file</a></p>
mysite/fileupload/templates/fileupload/fileupload_create.html
<h1>File upload</h1>
<form method = "post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.titlefield }}
{{ form.filefield }}
<input type = "submit" value = "Create" />
</form>
mysite/fileupload/templates/fileupload/fileupload_detail.html
<h1>File details</h1>
{% if fileupload_context %}
<ul>
<li>Primary Key Number : {{ fileupload_context.pk }}</li>
<li>Memo Text : {{ fileupload_context.titlefield }}</li>
<li>Memo Text : /media/{{ fileupload_context.filefield }}</li>
<li>File : <img src = /media/{{ fileupload_context.filefield }} /></li>
</ul>
{% else %}
<p>No file available.</p>
{% endif %}
<p><a href = "{% url 'site_index' %}">List files</a></p>
mysite/fileupload/templates/fileupload/fileupload_update.html
<h1>File update</h1>
<form method = "post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.titlefield }}
{{ form.filefield }}
<input type = "submit" value = "Save" />
</form>
mysite/fileupload/templates/fileupload/fileupload_delete.html
<h1>Delete file</h1>
<form method = "post">
{% csrf_token %}
<input type= "submit" value = "Delete" />
</form>
Once you've done the migration and started your development www server, You can access it at http: // localhost: 8000 / fileupload /.
The process when the file upload fails is not written properly, so it is a future issue.
The end
Recommended Posts