Django搭建YouTube克隆项目:首页视频缩略图无法加载求助
Django YouTube克隆项目缩略图无法显示问题
问题描述
我是Django新手,正在搭建YouTube克隆项目以深入掌握Django技术。启动服务器后,首页无法显示视频缩略图,已尝试多种方法仍未解决。
相关代码与信息
1) 模板文件
homeview.html
{% block body %} {% for video in most_recent_video %} <div class="video-card"> <img src="/get_thumbnail/{{ video.thumbnail.path }}" alt="{{ video.title }} thumbnail"> <h5>{{ video.title }}</h5> <p>Uploaded By {{ video.user }} on {{ video.datetime }}</p> <p>{{ video.description }}</p> <p><a href="/video/{{ video.id }}">Watch Video</a></p> </div> {% endfor %} {% endblock %}
thumbnail.html
{% block body %} <div class="header-bar"> <h2>Thumbnail View</h2> <hr> </div> <div class="main-body"> <form method="POST" enctype="multipart/form-data"> {% csrf_token %} <table> {{ form.as_p }} </table> <button type="submit">Upload Thumbnail</button> </form> {% if errors %} <div class="errors"> <h3>Errors:</h3> <ul> {% for field_errors in errors.values %} {% for error in field_errors %} <li>{{ error }}</li> {% endfor %} {% endfor %} </ul> </div> {% endif %} </div> {% endblock %}
2) views.py
class ThumbnailView(View): template_name = 'base/thumbnail.html' def get(self, request): if not request.user.is_authenticated: return HttpResponseRedirect('/login/') form = ThumbNailForm() return render(request, self.template_name, {'form': form}) def post(self, request): form = ThumbNailForm(request.POST, request.FILES) if form.is_valid(): # Create a new Thumbnail entry title = form.cleaned_data['title'] thumbnail_file = form.cleaned_data['file'] # Generate a random filename for the thumbnail random_chars = ''.join(random.choices( string.ascii_uppercase + string.digits, k=10)) filename = random_chars + thumbnail_file.name # Save the thumbnail file BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) thumbnail_path = os.path.join(BASE_DIR, filename) with open(thumbnail_path, 'wb') as f: f.write(thumbnail_file.read()) thumbnail = Thumbnail(title=title, path=filename) thumbnail.save() return HttpResponseRedirect('/home/') else: return render(request, self.template_name, {'form': form, 'errors': form.errors}) class ThumbnailFileView(View): def get(self, request, file_name): BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) stripped_file_name = file_name[10:] file = FileWrapper(open(os.path.join(BASE_DIR, stripped_file_name), 'rb')) response = HttpResponse(file, content_type='image/jpg') response['Content-Disposition'] = 'attachment; filename={}'.format(stripped_file_name) return response
3) urls.py
path('get_thumbnail/<file_name>', ThumbnailFileView.as_view(), name='getthumbnail'), path('thumbnail/', ThumbnailView.as_view(), name='thumbnail'),
4) models.py
class Video(models.Model): title = models.CharField(max_length=30) description = models.TextField(max_length=300) path = models.CharField(max_length=100) datetime = models.DateTimeField(auto_now=True ,blank=False, null=False) user = models.ForeignKey('auth.User', on_delete=models.CASCADE) likes = models.IntegerField(default=0) dislikes = models.IntegerField(default=0) class Thumbnail(models.Model): title = models.CharField(max_length=50) path = models.CharField(max_length=100) class ThumbnailView(models.Model): image = models.ForeignKey(Video, on_delete=models.CASCADE, related_name='thumbnails')
5) forms.py
class ThumbNailForm(forms.Form): title = forms.CharField(label='Title', max_length=50) file = forms.FileField()
6) 控制台错误信息
<QuerySet [<Video: Video object (43)>, <Video: Video object (42)>, <Video: Video object (41)>, <Video: Video object (40)>, <Video: Video object (39)>, <Video: Video object (38)>, <Video: Video object (37)>, <Video: Video object (36)>, <Video: Video object (35)>]> [01/Apr/2023 15:44:21] "GET /home/ HTTP/1.1" 200 16180 Not Found: /get_thumbnail/ [01/Apr/2023 15:44:21] "GET /get_thumbnail/ HTTP/1.1" 404 13168
7) 图片路径
C:\Users\Admin\Desktop\Youtube Redesign\Config\img1.jpg C:\Users\Admin\Desktop\Youtube Redesign\Config\img2.jpg C:\Users\Admin\Desktop\Youtube Redesign\Config\img3.jpg
问题分析与解决步骤
1. 模型关联缺失导致模板变量为空
控制台显示请求/get_thumbnail/无文件名,说明video.thumbnail.path为空。当前Video模型未与Thumbnail建立关联,模板中video.thumbnail不存在,导致URL拼接错误。
修复方法:
修改Video模型,添加缩略图外键关联,同时删除无用的ThumbnailView模型:
class Video(models.Model): title = models.CharField(max_length=30) description = models.TextField(max_length=300) path = models.CharField(max_length=100) datetime = models.DateTimeField(auto_now=True ,blank=False, null=False) user = models.ForeignKey('auth.User', on_delete=models.CASCADE) likes = models.IntegerField(default=0) dislikes = models.IntegerField(default=0) # 添加缩略图关联 thumbnail = models.ForeignKey(Thumbnail, on_delete=models.SET_NULL, null=True, blank=True) class Thumbnail(models.Model): title = models.CharField(max_length=50) path = models.CharField(max_length=100)
2. 文件存储与读取路径不匹配
你将缩略图保存在项目根目录,且在ThumbnailFileView中错误截取文件名前10位,导致文件找不到。同时未遵循Django媒体文件规范。
修复方法:
- 在项目
settings.py中配置媒体文件:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/'
创建项目根目录下的media文件夹。
- 修改
ThumbnailView的post方法,将文件保存到MEDIA_ROOT:
from django.conf import settings def post(self, request): form = ThumbNailForm(request.POST, request.FILES) if form.is_valid(): title = form.cleaned_data['title'] thumbnail_file = form.cleaned_data['file'] random_chars = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10)) filename = random_chars + thumbnail_file.name # 保存到media目录 file_path = os.path.join(settings.MEDIA_ROOT, filename) with open(file_path, 'wb') as f: f.write(thumbnail_file.read()) thumbnail = Thumbnail(title=title, path=filename) thumbnail.save() # 补充:需关联到对应Video,可在表单添加视频选择字段或调整上传逻辑 return HttpResponseRedirect('/home/') else: return render(request, self.template_name, {'form': form, 'errors': form.errors})
- 修改
ThumbnailFileView,直接读取媒体目录文件,取消文件名截取:
from django.conf import settings from django.http import HttpResponseNotFound class ThumbnailFileView(View): def get(self, request, file_name): file_path = os.path.join(settings.MEDIA_ROOT, file_name) if not os.path.exists(file_path): return HttpResponseNotFound("Thumbnail not found") file = FileWrapper(open(file_path, 'rb')) response = HttpResponse(file, content_type='image/jpeg') # 改为inline让图片直接显示,而非下载 response['Content-Disposition'] = 'inline; filename={}'.format(file_name) return response
3. URL路由参数格式错误
Django 2+需指定参数类型,否则无法正确匹配。修改urls.py:
path('get_thumbnail/<str:file_name>', ThumbnailFileView.as_view(), name='getthumbnail'),
4. 模板URL生成优化
使用Django的url标签生成正确URL,避免硬编码:
<img src="{% url 'getthumbnail' video.thumbnail.path %}" alt="{{ video.title }} thumbnail">
内容的提问来源于stack exchange,提问作者Salman Naqvi
相关产品推荐
相关产品推荐

