lzx02 6 months ago
parent 660cdb0720
commit b09c5c4ad2

2
.idea/.gitignore vendored

@ -1,4 +1,4 @@
# 默认忽略的文件 # Default ignored files
/shelf/ /shelf/
/workspace.xml /workspace.xml
# 基于编辑器的 HTTP 客户端请求 # 基于编辑器的 HTTP 客户端请求

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true"> <component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="Django default" uuid="4780d78e-bbdc-4708-aa57-23b7fa11976b"> <data-source source="LOCAL" name="Django default" uuid="3a0cb1a9-ffa1-40c6-9c58-1663dfce0708">
<driver-ref>mysql.8</driver-ref> <driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize> <synchronize>true</synchronize>
<imported>true</imported> <imported>true</imported>

@ -2,10 +2,22 @@
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="django-ratelimit" />
<item index="1" class="java.lang.String" itemvalue="sorl-thumbnail" />
<item index="2" class="java.lang.String" itemvalue="django_chunked_upload" />
<item index="3" class="java.lang.String" itemvalue="ratelimit" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers"> <option name="ignoredIdentifiers">
<list> <list>
<option value="server.myapp.admin.myapp" /> <option value="users.views.FeedbackView.*" />
</list> </list>
</option> </option>
</inspection_tool> </inspection_tool>

@ -1,4 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.8 (server)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (server)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (server)" project-jdk-type="Python SDK" />
</project> </project>

@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/.idea/videoproject-master.iml" filepath="$PROJECT_DIR$/.idea/videoproject-master.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/videoproject-master-4ec34161fdb4c9d953372c1b3fe44fa0a66876ec.iml" filepath="$PROJECT_DIR$/.idea/videoproject-master-4ec34161fdb4c9d953372c1b3fe44fa0a66876ec.iml" />
</modules> </modules>
</component> </component>
</project> </project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/video.sql" dialect="MySQL" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="videoproject/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
<option name="trackFilePattern" value="migrations" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.8 (server)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/templates" />
</list>
</option>
</component>
</module>

@ -1 +1 @@
# 初始化

@ -1,5 +1,6 @@
from django.contrib import admin from django.contrib import admin
from .models import * from .models import *
# Register your models here. # Register your models here.
admin.site.register(Comment) admin.site.register(Comment)

@ -1,5 +1,6 @@
from django.apps import AppConfig from django.apps import AppConfig
class CommentConfig(AppConfig): class CommentConfig(AppConfig):
name = 'comment' name = 'comment'

@ -1,5 +1,6 @@
import datetime import datetime
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models

@ -1,3 +1,4 @@
from django.test import TestCase from django.test import TestCase
# Create your tests here. # Create your tests here.

@ -2,6 +2,7 @@ from django.urls import path
from . import views from . import views
app_name = 'comment' app_name = 'comment'
urlpatterns = [ urlpatterns = [
path('submit_comment/<int:pk>',views.submit_comment, name='submit_comment'), path('submit_comment/<int:pk>',views.submit_comment, name='submit_comment'),

@ -10,6 +10,7 @@ from video.forms import CommentForm
from video.models import Video from video.models import Video
@ratelimit(key='ip', rate='2/m') @ratelimit(key='ip', rate='2/m')
def submit_comment(request,pk): def submit_comment(request,pk):
""" """

@ -9,7 +9,9 @@ from django.utils.html import strip_tags
from django.views.generic import View from django.views.generic import View
def get_page_list(paginator, page): def get_page_list(paginator, page):
""" """
分页逻辑 分页逻辑
if 页数>=10: if 页数>=10:
@ -36,10 +38,8 @@ def get_page_list(paginator, page):
return page_list return page_list
def ajax_required(f): def ajax_required(f):
"""Not a mixin, but a nice decorator to validate than a request is AJAX""" """Not a mixin, but a nice decorator to validate than a request is AJAX"""
def wrap(request, *args, **kwargs): def wrap(request, *args, **kwargs):
if not request.is_ajax(): if not request.is_ajax():
return HttpResponseBadRequest() return HttpResponseBadRequest()
@ -50,7 +50,6 @@ def ajax_required(f):
wrap.__name__ = f.__name__ wrap.__name__ = f.__name__
return wrap return wrap
def send_html_email(subject, html_message, to_list): def send_html_email(subject, html_message, to_list):
plain_message = strip_tags(html_message) plain_message = strip_tags(html_message)
from_email = settings.EMAIL_HOST_USER from_email = settings.EMAIL_HOST_USER
@ -58,6 +57,7 @@ def send_html_email(subject, html_message, to_list):
def send_email(subject, content, to_list): def send_email(subject, content, to_list):
""" """
Example: Example:
subject = 'test subject' subject = 'test subject'
@ -71,7 +71,7 @@ def send_email(subject, content, to_list):
# do not forget set password # do not forget set password
print("--> is sending email") print("--> is sending email")
send_mass_mail((message,)) send_mass_mail((message,))
except smtplib.SMTPException: except smtplib.SMTPException :
print("--> send fail") print("--> send fail")
return HttpResponse("fail") return HttpResponse("fail")
else: else:
@ -92,7 +92,6 @@ class AdminUserRequiredMixin(View):
""" """
管理员拦截器 管理员拦截器
""" """
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if not self.request.user.is_staff: if not self.request.user.is_staff:
return redirect('myadmin:login') return redirect('myadmin:login')
@ -104,9 +103,9 @@ class SuperUserRequiredMixin(View):
""" """
超级用户拦截器 超级用户拦截器
""" """
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if not self.request.user.is_superuser: if not self.request.user.is_superuser:
return HttpResponse('无权限') return HttpResponse('无权限')
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)

@ -2,8 +2,8 @@
import os import os
import sys import sys
if __name__ == '__main__':
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'videoproject.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'videoproject.settings')
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line

@ -1,2 +1,3 @@
from django.contrib import admin from django.contrib import admin

@ -1,6 +1,7 @@
from django.apps import AppConfig from django.apps import AppConfig
class MyadminConfig(AppConfig): class MyadminConfig(AppConfig):
name = 'myadmin' name = 'myadmin'

@ -2,6 +2,7 @@ from django import forms
from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import AuthenticationForm
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from users.models import User from users.models import User
from video.models import Video, Classification from video.models import Video, Classification

@ -1,6 +1,7 @@
from chunked_upload.models import ChunkedUpload from chunked_upload.models import ChunkedUpload
from django.db import models from django.db import models
# Create your models here. # Create your models here.
class MyChunkedUpload(ChunkedUpload): class MyChunkedUpload(ChunkedUpload):
pass pass

@ -1,3 +1,4 @@
from django.test import TestCase from django.test import TestCase
# Create your tests here. # Create your tests here.

@ -1,6 +1,7 @@
from django.urls import path from django.urls import path
from . import views from . import views
app_name = 'myadmin' app_name = 'myadmin'
urlpatterns = [ urlpatterns = [
path('login/', views.login, name='login'), path('login/', views.login, name='login'),

@ -1,6 +1,7 @@
import logging import logging
import smtplib import smtplib
import datetime import datetime
from chunked_upload.views import ChunkedUploadView, ChunkedUploadCompleteView from chunked_upload.views import ChunkedUploadView, ChunkedUploadCompleteView
from django.conf import settings from django.conf import settings

@ -199,10 +199,3 @@ body {
line-height:34px; line-height:34px;
color:#000; color:#000;
} }
.del {
width:100px;
height: 40px;
position: absolute;
right: 40px;
}

@ -3,7 +3,6 @@ $(function () {
// 写入csrf // 写入csrf
$.getScript("/static/js/csrftoken.js"); $.getScript("/static/js/csrftoken.js");
// 点赞 // 点赞
$("#like").click(function(){ $("#like").click(function(){
var video_id = $("#like").attr("video-id"); var video_id = $("#like").attr("video-id");

@ -44,11 +44,10 @@ $("#chunked_upload").fileupload({
console.log('file size --> ' + fileSize); console.log('file size --> ' + fileSize);
console.log('type --> ' + type); console.log('type --> ' + type);
// 若想限制大小,解开注释即可 if(fileSize > 100000000){
// if(fileSize > 10000000000){ alert('文件太大了请上传100M以内的文件');
// alert('文件太大了请上传10000M以内的文件'); return;
// return; }
// }
if(!type.startsWith("video/")){ if(!type.startsWith("video/")){
alert('视频格式不正确'); alert('视频格式不正确');

@ -17,7 +17,6 @@
</div> </div>
<div class="middle aligned content"> <div class="middle aligned content">
<a class="header" href="{% url 'video:detail' item.pk %}">{{ item.title }}</a> <a class="header" href="{% url 'video:detail' item.pk %}">{{ item.title }}</a>
<a class="del" onclick="uncollect({{item.id}})">取消收藏</a>
</div> </div>
</div> </div>
{% empty %} {% empty %}
@ -30,52 +29,4 @@
{% endblock content %} {% endblock content %}
{% block javascript %}
<script>
// 写入csrf
$.getScript("/static/js/csrftoken.js");
function uncollect(id) {
var x;
var r=confirm("确定删除?");
if (r==true){
console.log('click ok');
}
else{
return;
}
$.ajax({
url: '/video/collect/',
data: {
video_id: id,
'csrf_token': csrftoken
},
type: 'POST',
dataType: 'json',
success: function (data) {
var code = data.code
if(code == 0){
alert('删除成功')
window.location.reload()
}else{
var msg = data.msg
alert(msg)
}
},
error: function(data){
alert("收藏失败")
}
});
}
</script>
<script src="{% static 'js/detail.js' %}"></script>
{% endblock javascript %}

@ -17,7 +17,6 @@
</div> </div>
<div class="middle aligned content"> <div class="middle aligned content">
<a class="header" href="{% url 'video:detail' item.pk %}">{{ item.title }}</a> <a class="header" href="{% url 'video:detail' item.pk %}">{{ item.title }}</a>
<a class="del" onclick="unlike({{item.id}})">取消喜欢</a>
</div> </div>
</div> </div>
{% empty %} {% empty %}
@ -32,50 +31,3 @@
{% endblock content %} {% endblock content %}
{% block javascript %}
<script>
// 写入csrf
$.getScript("/static/js/csrftoken.js");
function unlike(id) {
var x;
var r=confirm("确定删除?");
if (r==true){
console.log('click ok');
}
else{
return;
}
$.ajax({
url: '/video/like/',
data: {
video_id: id,
'csrf_token': csrftoken
},
type: 'POST',
dataType: 'json',
success: function (data) {
var code = data.code
if(code == 0){
alert('删除成功')
window.location.reload()
}else{
var msg = data.msg
alert(msg)
}
},
error: function(data){
alert("收藏失败")
}
});
}
</script>
<script src="{% static 'js/detail.js' %}"></script>
{% endblock javascript %}

@ -2,7 +2,6 @@
<a target="_blank" href="https://promotion.aliyun.com/ntms/act/enterprise-discount.html?userCode=3bcjya8p"> <a target="_blank" href="https://promotion.aliyun.com/ntms/act/enterprise-discount.html?userCode=3bcjya8p">
<img src="{% static 'img/img_ad_banner.jpg' %}"> <img src="{% static 'img/img_ad_banner.jpg' %}">
</a> </a>

@ -5,6 +5,65 @@
<link rel="stylesheet" href="{% static 'css/dropload.css' %}"> <link rel="stylesheet" href="{% static 'css/dropload.css' %}">
{% endblock css %} {% endblock css %}
{% block content %}
<div class="ui unstackable two column grid">
<div class=" ten wide column">
<video class="video" autoplay="autoplay" controls="controls" controlslist="nodownload"
disablePictureInPicture>
<source src="{{video.file.url}}" type="video/mp4">
<!-- <source src="https://www.runoob.com/try/demo_source/movie.mp4" type="video/mp4">-->
</video>
<div class="video-info">
<div class="video-title">{{ video.title }}</div>
<div class="video-view-count">{{ video.view_count }}次观看</div>
<div class="video-view-operation">
{{video.desc}}
</div>
<div class="extra content video-view-operation">
<span class="left floated like">
<i class="like {% user_liked_class video user %} icon cursor" id="like"
video-id="{{ video.id }}"></i>
<span id="like-count">{{ video.count_likers }}</span>
</span>
<span class="right floated star">
<i class="bookmark {% user_collected_class video user %} icon cursor" id="star"
video-id="{{ video.id }}"></i>
<span id="collect-count">{{ video.count_collecters }}</span>
</span>
</div>
<div class="ui divider"></div>
</div>
<div class="ui comments">
{% if user.is_authenticated %}
<form class="ui reply form" id="comment_form" method="post"
action="{% url 'comment:submit_comment' video.pk %}">
{% csrf_token %}
<div class="field">
{{form.content}}
<input type="hidden" value="{{ video.id }}" name="video_id">
</div>
<button class="ui primary button" type="submit">
添加评论
</button>
<div class="ui info message n">
<div class="item" id="comment-result"></div>
</div>
</form>
{% else %}
<div class="ui ignored info attached message">
<p>登录后即可评论 &nbsp;&nbsp;&nbsp;<a href="{% url 'users:login' %}?next={{ request.path }}">马上登录</a></p>
</div>
{% endif %}
<h3 class="ui dividing header" id="id_comment_label">评论</h3>
<div class="comment-list"></div>
</div>
</div>
<div class="six wide column">
{% include "video/recommend.html" %}
{% include "video/ad.html" %}
</div>
</div>
{% endblock content %}
{% block javascript %} {% block javascript %}

@ -1,5 +1,6 @@
from django.contrib import admin from django.contrib import admin
# Register your models here. # Register your models here.
from .models import User from .models import User
admin.site.register(User) admin.site.register(User)

@ -1,3 +1,4 @@
from django.apps import AppConfig from django.apps import AppConfig

@ -3,6 +3,7 @@ from django.db import models
class User(AbstractUser): class User(AbstractUser):
GENDER_CHOICES = ( GENDER_CHOICES = (
('M', ''), ('M', ''),

@ -1,3 +1,4 @@
from django.test import TestCase from django.test import TestCase
# Create your tests here. # Create your tests here.

@ -1,6 +1,7 @@
from django.urls import path from django.urls import path
from . import views from . import views
app_name = 'users' app_name = 'users'
urlpatterns = [ urlpatterns = [
path('login/', views.login, name='login'), path('login/', views.login, name='login'),

@ -8,15 +8,146 @@ from django.shortcuts import *
from django.views import generic from django.views import generic
from ratelimit.decorators import ratelimit from ratelimit.decorators import ratelimit
from .models import Feedback from .models import Feedback
from .forms import ProfileForm, SignUpForm, UserLoginForm, ChangePwdForm, SubscribeForm, FeedbackForm from .forms import ProfileForm, SignUpForm, UserLoginForm, ChangePwdForm, SubscribeForm, FeedbackForm
User = get_user_model() User = get_user_model()
def login(request): def login(request):
# 功能待开发,请期待 if request.method == 'POST':
next = request.POST.get('next', '/')
form = UserLoginForm(request=request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
auth_login(request, user)
# return redirect('home')
return redirect(next)
else:
print(form.errors)
else:
next = request.GET.get('next', '/')
form = UserLoginForm()
print(next)
return render(request, 'registration/login.html', {'form': form, 'next':next})
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password1 = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password1)
auth_login(request, user)
return redirect('home')
else:
print(form.errors)
else:
form = SignUpForm()
return render(request, 'registration/signup.html', {'form': form})
def logout(request):
auth_logout(request)
return redirect('home')
def change_password(request):
if request.method == 'POST':
form = ChangePwdForm(request.user, request.POST)
if form.is_valid():
user = form.save(commit=False)
if not user.is_staff and not user.is_superuser:
user.save()
update_session_auth_hash(request, user) # 更新session 非常重要!
messages.success(request, '修改成功')
return redirect('users:change_password')
else:
messages.warning(request, '无权修改管理员密码')
return redirect('users:change_password')
else:
print(form.errors)
else:
form = ChangePwdForm(request.user)
return render(request, 'registration/change_password.html', {
'form': form
})
class ProfileView(LoginRequiredMixin,AuthorRequiredMixin, generic.UpdateView):
model = User
form_class = ProfileForm
template_name = 'users/profile.html'
def get_success_url(self):
messages.success(self.request, "保存成功")
return reverse('users:profile', kwargs={'pk': self.request.user.pk})
class SubscribeView(LoginRequiredMixin,AuthorRequiredMixin, generic.UpdateView):
model = User
form_class = SubscribeForm
template_name = 'users/subscribe.html'
def get_success_url(self):
messages.success(self.request, "保存成功")
return reverse('users:subscribe', kwargs={'pk': self.request.user.pk})
class FeedbackView(LoginRequiredMixin, generic.CreateView):
model = Feedback
form_class = FeedbackForm
template_name = 'users/feedback.html'
@ratelimit(key='ip', rate='2/m')
def post(self, request, *args, **kwargs):
was_limited = getattr(request, 'limited', False)
if was_limited:
messages.warning(self.request, "操作太频繁了请1分钟后再试")
return render(request, 'users/feedback.html', {'form': FeedbackForm()})
return super().post(request, *args, **kwargs)
def get_success_url(self):
messages.success(self.request, "提交成功")
return reverse('users:feedback')
class CollectListView(generic.ListView):
model = User
template_name = 'users/collect_videos.html'
context_object_name = 'video_list'
paginate_by = 10
def get_context_data(self, *, object_list=None, **kwargs):
context = super(CollectListView, self).get_context_data(**kwargs)
paginator = context.get('paginator')
page = context.get('page_obj')
page_list = get_page_list(paginator, page)
context['page_list'] = page_list
return context
def get_queryset(self):
user = get_object_or_404(User, pk=self.kwargs.get('pk'))
videos = user.collected_videos.all()
return videos
class LikeListView(generic.ListView):
model = User
template_name = 'users/like_videos.html'
context_object_name = 'video_list'
paginate_by = 10
def get_context_data(self, *, object_list=None, **kwargs):
context = super(LikeListView, self).get_context_data(**kwargs)
paginator = context.get('paginator')
page = context.get('page_obj')
page_list = get_page_list(paginator, page)
context['page_list'] = page_list
return context
def get_queryset(self): def get_queryset(self):
user = get_object_or_404(User, pk=self.kwargs.get('pk')) user = get_object_or_404(User, pk=self.kwargs.get('pk'))

@ -3,6 +3,7 @@
chdir = /var/www/videoproject chdir = /var/www/videoproject
module = videoproject.wsgi module = videoproject.wsgi
master = true master = true
processes = 2 processes = 2
#socket = /run/uwsgi/video-conf.sock #socket = /run/uwsgi/video-conf.sock
@ -15,5 +16,3 @@ gid = www-data
vacuum = true vacuum = true
daemonize = %(chdir)/uwsgi.log daemonize = %(chdir)/uwsgi.log
#

@ -1,6 +1,7 @@
from django.contrib import admin from django.contrib import admin
from .models import * from .models import *
# Register your models here.) # Register your models here.)
admin.site.register(Classification) admin.site.register(Classification)
admin.site.register(Video) admin.site.register(Video)

@ -1,5 +1,6 @@
from django.apps import AppConfig from django.apps import AppConfig
class VideoConfig(AppConfig): class VideoConfig(AppConfig):
name = 'video' name = 'video'

@ -1,6 +1,7 @@
from django import forms from django import forms
from comment.models import Comment from comment.models import Comment
class CommentForm(forms.ModelForm): class CommentForm(forms.ModelForm):
content = forms.CharField(error_messages={'required': '不能为空',}, content = forms.CharField(error_messages={'required': '不能为空',},
widget=forms.Textarea(attrs = {'placeholder': '请输入评论内容' }) widget=forms.Textarea(attrs = {'placeholder': '请输入评论内容' })

@ -5,6 +5,7 @@ from django.db import models
from django.dispatch import receiver from django.dispatch import receiver
class VideoQuerySet(models.query.QuerySet): class VideoQuerySet(models.query.QuerySet):
def get_count(self): def get_count(self):

@ -1,3 +1,4 @@
from django.test import TestCase from django.test import TestCase
# Create your tests here. # Create your tests here.

@ -1,6 +1,7 @@
from django.urls import path from django.urls import path
from . import views from . import views
app_name = 'video' app_name = 'video'
urlpatterns = [ urlpatterns = [
path('index', views.IndexView.as_view(), name='index'), path('index', views.IndexView.as_view(), name='index'),

@ -3,6 +3,7 @@ from django.shortcuts import get_object_or_404
from django.views import generic from django.views import generic
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
from helpers import get_page_list, ajax_required from helpers import get_page_list, ajax_required
from .forms import CommentForm from .forms import CommentForm
from .models import Video, Classification from .models import Video, Classification
@ -56,9 +57,45 @@ class SearchListView(generic.ListView):
return context return context
class VideoDetailView(generic.DetailView):
model = Video
template_name = 'video/detail.html'
def get_object(self, queryset=None):
obj = super().get_object()
obj.increase_view_count()
return obj
def get_context_data(self, **kwargs):
context = super(VideoDetailView, self).get_context_data(**kwargs)
form = CommentForm()
recommend_list = Video.objects.get_recommend_list()
context['form'] = form
context['recommend_list'] = recommend_list
return context
@ajax_required
@require_http_methods(["POST"])
def like(request):
if not request.user.is_authenticated:
return JsonResponse({"code": 1, "msg": "请先登录"})
video_id = request.POST['video_id']
video = Video.objects.get(pk=video_id)
user = request.user
video.switch_like(user)
return JsonResponse({"code": 0, "likes": video.count_likers(), "user_liked": video.user_liked(user)})
@ajax_required
@require_http_methods(["POST"])
def collect(request):
if not request.user.is_authenticated:
return JsonResponse({"code": 1, "msg": "请先登录"})
video_id = request.POST['video_id']
video = Video.objects.get(pk=video_id)
user = request.user
video.switch_collect(user)
return JsonResponse({"code": 0, "collects": video.count_collecters(), "user_collected": video.user_collected(user)})

@ -1,4 +1,5 @@
import pymysql import pymysql
pymysql.install_as_MySQLdb() pymysql.install_as_MySQLdb()
print("===============install pymysql==============") print("===============install pymysql==============")

@ -71,7 +71,7 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'upload').replace('\\', '/')
MEDIA_URL = '/upload/' MEDIA_URL = '/upload/'
# 上传视频最大尺寸 # 上传视频最大尺寸
CHUNKED_UPLOAD_MAX_BYTES = 10000000000 CHUNKED_UPLOAD_MAX_BYTES = 100000000
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
@ -98,6 +98,7 @@ TEMPLATES = [
}, },
] ]
WSGI_APPLICATION = 'videoproject.wsgi.application' WSGI_APPLICATION = 'videoproject.wsgi.application'
# Database # Database

@ -1,5 +1,6 @@
""" URL Configuration """ URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see: The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/ https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples: Examples:

@ -1,6 +1,7 @@
""" """
WSGI config for dj_demo_one project. WSGI config for dj_demo_one project.
It exposes the WSGI callable as a module-level variable named ``application``. It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see For more information on this file, see

Loading…
Cancel
Save