Django上传图片和显示图片
在搭建网站时,难免需要上传图片,比如用户头像或者相册图片等等,这里简单记录一下过程。
上传和显示
新建一个工程
$ django-admin startproject django_upload_example
$ tree django_upload_example
django_upload_example
├── django_upload_example
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
$ cd django_upload_example
$ pwd
/home/user/django_upload_example
新建一个应用
$ python manage.py startapp users
注册应用
# django_upload_example/settings.py
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users'
]
...
数据模型
# users/models.py
from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=50)
# upload_to 指定上传文件位置
# 这里指定存放在 img/ 目录下
headimg = models.FileField(upload_to="img/")
# 返回名称
def __str__(self):
return self.name
# django_upload_example/settings.py
...
# 指定上传文件目录
# replace() 将 "\\" 替换为 "/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace("\\", "/")
MEDIA_URL = '/media/'
...
数据库迁移
$ python manage.py makemigrations
Migrations for 'users':
users/migrations/0001_initial.py
- Create model User
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying sessions.0001_initial... OK
Applying users.0001_initial... OK
url
# django_upload_example/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# 使用 include() 将 users 应用的 urls 模块包含进来
path('users/', include('users.urls'))
]
# users/urls.py
from django.urls import path
from . import views
app_name = 'users'
urlpatterns = [
path('add/', views.add, name='add'),
]
forms
# users/forms.py
from django import forms
# 表单类用以生成表单
class AddForm(forms.Form):
name = forms.CharField()
headimg = forms.FileField()
视图函数
# users/views.py
from django.shortcuts import render
from .models import User
from .forms import AddForm
# Create your views here.
def add(request):
# 判断是否为 post 方法提交
if request.method == "POST":
af = AddForm(request.POST, request.FILES)
# 判断表单值是否和法
if af.is_valid():
name = af.cleaned_data['name']
headimg = af.cleaned_data['headimg']
user = User(name=name, headimg=headimg)
user.save()
return render(request, 'users/index.html', context={"user":user})
else:
af = AddForm()
return render(request, 'users/add.html', context={"af":af})
模板
# django_upload_example/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
<!-- templates/users/add.html -->
<!doctype html>
<html>
<head>
<title>Add</title>
<meta charset="utf-8">
</head>
<body>
<h1>Add!</h1>
<form method="post" enctype="multipart/form-data" action="{% url 'users:add' %}">
{% csrf_token %}
{{ af.as_p }}
<input type="submit" value="OK"/>
</form>
</body>
</html>
<!-- templates/users/index.html -->
<!doctype html>
<html>
<head>
<title>Detail</title>
<meta charset="utf-8">
</head>
<body>
<p>{{ user.name }}</p>
<img width="50%" height="50%" src="/media/{{ user.headimg }}">
</body>
</html>
测试
$ python manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
July 24, 2018 - 07:28:55
Django version 2.0.4, using settings 'django_upload_example.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
登陆 127.0.0.1:8000/users/add/
image
填写表单之后点击确定,发现图片无法显示
image
# 查看目录发现 已经上传了
$ ls
db.sqlite3 django_upload_example manage.py media templates users
$ tree media
media
└── img
└── 1.jpg
配置
# django_upload_example/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('users.urls'))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
image
完成