Python学习笔记:7.4.4 Django快速建站 - 上传文件

前言:本文是学习网易微专业的《python全栈工程师 - Django快速建站》课程的笔记,欢迎学习交流。同时感谢老师们的精彩传授!

一、课程目标

  • 实现上传文件功能
  • 播放视频
  • 下载文件

二、详情解读

2.1.上传文件功能
2.1.1.功能
  • 为课程上传视频文件和附件
    – 视频文件和附件文件保存到服务器
  • 浏览课程
    – 在线观看视频文件
    – 下载附件
2.2.开发过程
2.2.1.上传
  • models.pyCourse增加两个字段:
    video = models.FileField(blank=True, upload_to='videos/')
    attach = models.FileField(blank=True, upload_to=user_directory_path)

说明:这里blank=True都默认为空,是因为数据库已经有数据了,如果新增的字段不默认为空,则需要为它们添加数据,为图省事,这里都默认为空。

  • 迁移数据
python3 manage.py makemigrations course
python3 manage.py migrate
  • settings.py,配置文件存储位置
    MEDIA_URL='/media/'
    MEDIA_ROOT=os.path.join(BASE_DIR, 'media')
  • forms.py增加字段
    fields = ('title', 'overview', 'video', 'attach')
  • views.py,修改类视图CourseCreateView
    fields = ['title', 'overview', 'video', 'attach' ]
    form = CourseCreatedForm(request.POST, request.FILES)
  • course_create.html,修改模板

实操一: 上传课程文件

step1:新增字段。编辑文件myproject/course/models.py

from django.db import models
from django.contrib.auth.models import User

# new
def user_directory_path(instance, filename):
    return 'courses/user_{0}/{1}'.format(instance.user.id, filename)

class Course(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='course_user')
    title = models.CharField(max_length=30)
    overview = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    video = models.FileField(blank=True, upload_to='videos/') # new
    attach = models.FileField(blank=True, upload_to=user_directory_path) # new

    class Meta:
        """
         内部类设置排序字段,以创建时间的倒序排序
        """
        ordering = ('-created',)

    def __str__(self):
        return self.title

说明
1).新增函数user_directory_path,返回附件的上传路径。
2).新增字段video、attach,注意upload_to的不同写法。

Step2:迁移数据

python3 manage.py makemigrations course
python3 manage.py migrate

Step3:配置文件存储位置。

# myproject/mysite/settings.py文件
.
.
.
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

Step4:创建目录myproject/media/
Step5:增加字段。修改文件myproject/course/forms.py

from django import forms
from .models import Course

class CourseCreateForm(forms.ModelForm):
    class Meta:
        model = Course
        fields = ('title', 'overview', 'video', 'attach') # new

Step6:修改文件myproject/course/views.py中的类视图CourseCreateView

.
.
.
class CourseCreateView(UserCourseMixin, CreateView):
    fields = ['title', 'overview', 'video', 'attach'] # modified
    template_name = 'course/course_create.html'

    def post(self, request, *args, **kwargs):
        form = CourseCreateForm(request.POST, request.FILES) #modified
        if form.is_valid():
            new_course = form.save(commit=False)
            new_course.user = self.request.user
            new_course.save()
            return redirect('course:course_list')
        return self.render_to_response({'form': form})

.
.
.

Step7:修改模板文件myproject/templates/course/course_create.html

{% extends 'base.html' %}
{% block title %}Create Course{% endblock %}

{% block content %}
<div class="container">
    <form action="." method="post" enctype="multipart/form-data">
        {% csrf_token %}
        
        <div style="margin-top: 10px">
            <div class="col-md-2 text-left">课程标题:div>
            <div class="col-md-10 text-left">{{ form.title }}div>
        div>
        <div style="margin-top: 10px">
            <div class="col-md-2 text-left">课程介绍:div>
            <div class="col-md-10 text-left">{{ form.overview }}div>
        div>
        <div style="margin-top: 10px">
            <div class="col-md-2 text-left">上传视频:div>
            <div class="col-md-10 text-left">{{ form.video }}div>
        div>
        <div style="margin-top: 10px">
            <div class="col-md-2 text-left">上传附件:div>
            <div class="col-md-10 text-left">{{ form.attach }}div>
        div>
        <input type="submit" value="发布课程">
    form>
div>
{% endblock %}

说明:
1).添加enctype="multipart/form-data"属性,上传文件表单必须设置的,否则无法接收文件。

运行结果:
Python学习笔记:7.4.4 Django快速建站 - 上传文件_第1张图片

2.2.2.查看
  • 模板: course_list.html
<a href="{% url 'course:course_detail' course.id %}">
	<span class="glyphicon glyphicon-search" style="margin-left: 20px;">span>
a>
  • views.py,创建类视图
    from django.views.generic import DetailView
    class CourseDetailView(UserCourseMixin, DetailView)
  • 创建模板:course/course_detail.html
  • 配置URL
    – 在mysite/urls.py中为上传文件创建url
    – 在course/urls.py配置查看路由

实操二: 查看课程内容

Step1:修改模板文件myproject/templates/course/course_list.html,添加查看课程详情按钮。

.
.
.
                <td>
                    <a href="{% url 'course:course_delete' course.id %}" class="delete"  name="delete">
                        <span class="glyphicon glyphicon-trash" style="margin-left:20px;">span>
                    a>
                    
                     <a href="{% url 'course:course_detail' course.id %}">
                        <span class="glyphicon glyphicon-search" style="margin-left:20px;">span>
                    a>
                td>
            tr>
        {% endfor %}
    table>
div>
<script src="{% static 'js/jquery-3.4.1.js' %}">script>
.
.
.

Step2:创建类视图。修改文件myproject/course/view.py

from django.shortcuts import render
from django.views.generic import TemplateView, ListView, DetailView # modified
from .models import Course
from braces.views import LoginRequiredMixin
.
.
.
# new
class CourseDetailView(UserCourseMixin, DetailView):
    template_name = 'course/course_detail.html'

Step3:创建模板文件。myproject/templates/course/course_detail.html

{% extends 'base.html' %}

{% block title %}Course Detail{% endblock %}
{% block content %}
<div class="row vertical-middle-sm">
    <h1 class="text-center">{{ object.title }}h1>
    <p class="text-center">讲师:{{ object.user.username }}p>
    <p>简介:{{ object.overview }}p>
    {% if object.video %}
        <div class="text-center">
            <video src="{{ object.video.url }}" class="text-center" controls="controls" width="800">video>
        div>
    {% else %}
        <p>没有视频p>
    {% endif %}
    {% if object.attach %}
        <p>下载课件:<a href="{{ object.attach.url }}">{{ object.attach.name|slice:"15:" }}a>p>
    {% endif %}
div>
{% endblock %}

说明:
1).由于类视图CourseDetailView中没有声明类似这个变量context_object_name="courses",所以模板中渲染时用object
2).因为视频和附件可有可无,所以渲染模板时需要做if判断。
3).slice:"15:"|后面的是过滤器,类似切片,表示从第15个字符后开始显示。

Step4:配置路由1,myproject/mysite/urls.py


from django.contrib import admin
from django.urls import path, include

# new 
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls', namespace='blog')),
    path('account/', include('account.urls', namespace='account')),
    path('course/', include('course.urls', namespace='course')),
]

urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT) # new

配置路由2,myproject/course/urls.py

# -*- coding=utf-8 -*-
from django.urls import path
# from django.views.generic import TemplateView
from .views import CourseHome, CourseListView, CourseCreateView, CourseDeleteView, CourseDetailView #new

app_name = 'course'

urlpatterns = [
	# path('', TemplateView.as_view(template_name='course/home.html')),
	path('', CourseHome.as_view()),
	path('course-list/', CourseListView.as_view(), name='course_list'), 
	path('course-create/', CourseCreateView.as_view(), name='course_create'),
	path('course-delete//', CourseDeleteView.as_view(), name='course_delete'),
	path('course-detail//', CourseDetailView.as_view(), name='course_detail'), #new
]

运行结果:
Python学习笔记:7.4.4 Django快速建站 - 上传文件_第2张图片

三、课程小结

  • 01 上传文件
  • 02 显示播放视频和文件下载

你可能感兴趣的:(Python全栈工程师学习笔记)