Django上传图片和显示图片

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

完成

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容