lzx02 6 months ago
parent b09c5c4ad2
commit 59fb4e8c99

Binary file not shown.

@ -5,9 +5,6 @@
<div class="ui divider"></div>
<img src="{% static 'img/logo.png' %}" class="ui centered mini image">
<div class="ui horizontal small divided link list">
<a class="item" href="#">北京堆栈科技有限公司</a>
<a class="item" href="#">联系我们</a>
<a class="item" href="#">京ICP证090287</a>
</div>
</div>
</div>

@ -36,7 +36,7 @@
</div>
</div>
{% empty %}
<h3>暂无数据</h3>
<h3>暂无数据</h3>w
{% endfor %}
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

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

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

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

@ -0,0 +1,110 @@
import os
from django.conf import settings
from django.db import models
from django.dispatch import receiver
class VideoQuerySet(models.query.QuerySet):
def get_count(self):
return self.count()
def get_published_count(self):
return self.filter(status=0).count()
def get_not_published_count(self):
return self.filter(status=1).count()
def get_published_list(self):
return self.filter(status=0).order_by('-create_time')
def get_search_list(self, q):
if q:
return self.filter(title__contains=q).order_by('-create_time')
else:
return self.order_by('-create_time')
def get_recommend_list(self):
return self.filter(status=0).order_by('-view_count')[:4]
class Classification(models.Model):
list_display = ("title",)
title = models.CharField(max_length=100,blank=True, null=True)
status = models.BooleanField(default=True)
def __str__(self):
return self.title
class Meta:
db_table = "v_classification"
class Video(models.Model):
STATUS_CHOICES = (
('0', '发布中'),
('1', '未发布'),
)
title = models.CharField(max_length=100,blank=True, null=True)
desc = models.CharField(max_length=255,blank=True, null=True)
classification = models.ForeignKey(Classification, on_delete=models.CASCADE, null=True)
file = models.FileField(max_length=255)
cover = models.ImageField(upload_to='cover/',blank=True, null=True)
status = models.CharField(max_length=1 ,choices=STATUS_CHOICES, blank=True, null=True)
view_count = models.IntegerField(default=0, blank=True)
liked = models.ManyToManyField(settings.AUTH_USER_MODEL,
blank=True, related_name="liked_videos")
collected = models.ManyToManyField(settings.AUTH_USER_MODEL,
blank=True, related_name="collected_videos")
create_time = models.DateTimeField(auto_now_add=True, blank=True, max_length=20)
objects = VideoQuerySet.as_manager()
class Meta:
db_table = "v_video"
def increase_view_count(self):
self.view_count += 1
self.save(update_fields=['view_count'])
def switch_like(self, user):
if user in self.liked.all():
self.liked.remove(user)
else:
self.liked.add(user)
def count_likers(self):
return self.liked.count()
def user_liked(self, user):
if user in self.liked.all():
return 0
else:
return 1
def switch_collect(self, user):
if user in self.collected.all():
self.collected.remove(user)
else:
self.collected.add(user)
def count_collecters(self):
return self.collected.count()
def user_collected(self, user):
if user in self.collected.all():
return 0
else:
return 1
@receiver(models.signals.post_delete, sender=Video)
def auto_delete_file_on_delete(sender, instance, **kwargs):
"""
删除FileField文件
"""
if instance.file:
if os.path.isfile(instance.file.path):
os.remove(instance.file.path)

@ -0,0 +1,41 @@
from datetime import date, datetime
from django.utils.timezone import is_aware, utc
from django import template
register = template.Library()
@register.filter
def time_since(value, default="刚刚"):
if not isinstance(value, date): # datetime is a subclass of date
return value
now = datetime.now(utc if is_aware(value) else None)
diff = now - value
periods = (
(diff.days / 365, ""),
(diff.days / 30, "个月"),
(diff.days / 7, ""),
(diff.days, ""),
(diff.seconds / 3600, "小时"),
(diff.seconds / 60, "分钟"),
(diff.seconds, ""),
)
for period, singular in periods:
if int(period) > 0:
return "%d%s" % (period, singular)
return default
@register.simple_tag
def user_liked_class(video, user):
liked = video.user_liked(user)
if liked == 0:
return "red"
else:
return "grey"
@register.simple_tag
def user_collected_class(video, user):
collected = video.user_collected(user)
if collected == 0:
return "red"
else:
return "grey"

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

@ -0,0 +1,11 @@
from django.urls import path
from . import views
app_name = 'video'
urlpatterns = [
path('index', views.IndexView.as_view(), name='index'),
path('search/', views.SearchListView.as_view(), name='search'),
path('detail/<int:pk>/', views.VideoDetailView.as_view(), name='detail'),
path('like/', views.like, name='like'),
path('collect/', views.collect, name='collect'),
]

@ -0,0 +1,100 @@
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.views import generic
from django.views.decorators.http import require_http_methods
from helpers import get_page_list, ajax_required
from .forms import CommentForm
from .models import Video, Classification
class IndexView(generic.ListView):
model = Video
template_name = 'video/index.html'
context_object_name = 'video_list'
paginate_by = 12
c = None
def get_context_data(self, *, object_list=None, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
paginator = context.get('paginator')
page = context.get('page_obj')
page_list = get_page_list(paginator, page)
classification_list = Classification.objects.filter(status=True).values()
context['c'] = self.c
context['classification_list'] = classification_list
context['page_list'] = page_list
return context
def get_queryset(self):
self.c = self.request.GET.get("c", None)
if self.c:
classification = get_object_or_404(Classification, pk=self.c)
return classification.video_set.all().order_by('-create_time')
else:
return Video.objects.filter(status=0).order_by('-create_time')
class SearchListView(generic.ListView):
model = Video
template_name = 'video/search.html'
context_object_name = 'video_list'
paginate_by = 8
q = ''
def get_queryset(self):
self.q = self.request.GET.get("q", "")
return Video.objects.filter(title__contains=self.q).filter(status=0)
def get_context_data(self, *, object_list=None, **kwargs):
context = super(SearchListView, 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
context['q'] = self.q
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)})

@ -182,7 +182,7 @@ CREATE TABLE `django_migrations` (
LOCK TABLES `django_migrations` WRITE;
/*!40000 ALTER TABLE `django_migrations` DISABLE KEYS */;
INSERT INTO `django_migrations` VALUES (1,'contenttypes','0001_initial','2022-12-08 21:18:07.268524'),(2,'contenttypes','0002_remove_content_type_name','2022-12-08 21:18:07.393539'),(3,'auth','0001_initial','2022-12-08 21:18:07.799782'),(4,'auth','0002_alter_permission_name_max_length','2022-12-08 21:18:07.893540'),(5,'auth','0003_alter_user_email_max_length','2022-12-08 21:18:07.909163'),(6,'auth','0004_alter_user_username_opts','2022-12-08 21:18:07.909163'),(7,'auth','0005_alter_user_last_login_null','2022-12-08 21:18:07.924789'),(8,'auth','0006_require_contenttypes_0002','2022-12-08 21:18:07.924789'),(9,'auth','0007_alter_validators_add_error_messages','2022-12-08 21:18:07.940407'),(10,'auth','0008_alter_user_username_max_length','2022-12-08 21:18:07.940407'),(11,'auth','0009_alter_user_last_name_max_length','2022-12-08 21:18:07.956032'),(12,'users','0001_initial','2022-12-08 21:18:08.487275'),(13,'admin','0001_initial','2022-12-08 21:18:08.799788'),(14,'admin','0002_logentry_remove_auto_add','2022-12-08 21:18:08.799788'),(15,'admin','0003_logentry_add_action_flag_choices','2022-12-08 21:18:08.815394'),(16,'auth','0010_alter_group_name_max_length','2022-12-08 21:18:09.643528'),(17,'auth','0011_update_proxy_permissions','2022-12-08 21:18:09.659160'),(18,'auth','0012_alter_user_first_name_max_length','2022-12-08 21:18:09.659160'),(19,'video','0001_initial','2022-12-08 21:18:10.237286'),(20,'comment','0001_initial','2022-12-08 21:18:10.424779'),(21,'myadmin','0001_initial','2022-12-08 21:18:10.549793'),(22,'myadmin','0002_setting','2022-12-08 21:18:10.596645'),(23,'myadmin','0003_delete_setting','2022-12-08 21:18:10.612280'),(24,'sessions','0001_initial','2022-12-08 21:18:10.721655'),(25,'thumbnail','0001_initial','2022-12-08 21:18:10.799793'),(26,'users','0002_auto_20181226_2050','2022-12-08 21:18:10.893555'),(27,'users','0003_auto_20220616_2056','2022-12-08 21:18:11.049782'),(28,'video','0002_video_status','2022-12-08 21:18:11.143528'),(29,'video','0003_video_cover','2022-12-08 21:18:11.237279'),(30,'video','0004_auto_20181222_1959','2022-12-08 21:18:11.346655'),(31,'video','0005_auto_20181223_1531','2022-12-08 21:18:11.471653'),(32,'video','0006_auto_20181223_1547','2022-12-08 21:18:11.487275'),(33,'video','0007_auto_20181225_2052','2022-12-08 21:18:11.502891'),(34,'video','0008_classification','2022-12-08 21:18:11.659152'),(35,'video','0009_auto_20181228_1519','2022-12-08 21:18:11.909158'),(36,'video','0010_alter_video_cover','2022-12-08 21:18:11.924777');
INSERT INTO `django_migrations` VALUES (1,'contenttypes','0001_initial','2022-12-08 21:18:07.268524'),(2,'contenttypes','0002_remove_content_type_name','2022-12-08 21:18:07.393539'),(3,'auth','0001_initial','2022-12-08 21:18:07.799782'),(4,'auth','0002_alter_permission_name_max_length','2022-12-08 21:18:07.893540'),(5,'auth','0003_alter_user_email_max_length','2022-12-08 21:18:07.909163'),(6,'auth','0004_alter_user_username_opts','2022-12-08 21:18:07.909163'),(7,'auth','0005_alter_user_last_login_null','2022-12-08 21:18:07.924789'),(8,'auth','0006_require_contenttypes_0002','2022-12-08 21:18:07.924789'),(9,'auth','0007_alter_validators_add_error_messages','2022-12-08 21:18:07.940407'),(10,'auth','0008_alter_user_username_max_length','2022-12-08 21:18:07.940407'),(11,'auth','0009_alter_user_last_name_max_length','2022-12-08 21:18:07.956032'),(12,'users','0001_initial','2022-12-08 21:18:08.487275'),(13,'admin','0001_initial','2022-12-08 21:18:08.799788'),(14,'admin','0002_logentry_remove_auto_add','2022-12-08 21:18:08.799788'),(15,'admin','0003_logentry_add_action_flag_choices','2022-12-08 21:18:08.815394'),(16,'auth','0010_alter_group_name_max_length','2022-12-08 21:18:09.643528'),(17,'auth','0011_update_proxy_permissions','2022-12-08 21:18:09.659160'),(18,'auth','0012_alter_user_first_name_max_length','2022-12-08 21:18:09.659160'),(19,'video','0001_initial','2022-12-08 21:18:10.237286'),(20,'comment','0001_initial','2022-12-08 21:18:10.424779'),(21,'myadmin','0001_initial','2022-12-08 21:18:10.549793'),(22,'myadmin','0002_setting','2022-12-08 21:18:10.596645'),(23,'myadmin','0003_delete_setting','2022-12-08 21:18:10.612280'),(24,'sessions','0001_initial','2022-12-08 21:18:10.721655'),(25,'thumbnail','0001_initial','2022-12-08 21:18:10.799793'),(26,'users','0002_auto_20181226_2050','2022-12-08 21:18:10.893555'),(27,'users','0003_auto_20220616_2056','2022-12-08 21:18:11.049782'),(28,'video','0002_video_status','2022-12-08 21:18:11.143528'),(29,'video','0003_video_cover','2022-12-08 21:18:11.237279'),(30,'video','0004_auto_20181222_1959','2022-12-08 21:18:11.346655'),(31,'video','0005_auto_20181223_1531','2022-12-08 21:18:11.471653'),(32,'video','0006_auto_20181223_1547','2022-12-08 21:18:11.487275'),(33,'video','0007_auto_20181225_2052','2022-12- 08 21:18:11.502891'),(34,'video','0008_classification','2022-12-08 21:18:11.659152'),(35,'video','0009_auto_20181228_1519','2022-12-08 21:18:11.909158'),(36,'video','0010_alter_video_cover','2022-12-08 21:18:11.924777');
/*!40000 ALTER TABLE `django_migrations` ENABLE KEYS */;
UNLOCK TABLES;

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

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

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

@ -5,7 +5,6 @@ from django.db import models
from django.dispatch import receiver
class VideoQuerySet(models.query.QuerySet):
def get_count(self):
@ -47,16 +46,16 @@ class Video(models.Model):
('1', '未发布'),
)
title = models.CharField(max_length=100,blank=True, null=True)
desc = models.CharField(max_length=255,blank=True, null=True)
desc = models.CharField(max_length=255,blank=True, null=True);'描述'
classification = models.ForeignKey(Classification, on_delete=models.CASCADE, null=True)
file = models.FileField(max_length=255)
cover = models.ImageField(upload_to='cover/',blank=True, null=True)
status = models.CharField(max_length=1 ,choices=STATUS_CHOICES, blank=True, null=True)
file = models.FileField(max_length=255) ;"地址"
cover = models.ImageField(upload_to='cover/',blank=True, null=True);'''封面'''
status = models.CharField(max_length=1 ,choices=STATUS_CHOICES, blank=True, null=True);'视频状态'
view_count = models.IntegerField(default=0, blank=True)
liked = models.ManyToManyField(settings.AUTH_USER_MODEL,
blank=True, related_name="liked_videos")
blank=True, related_name="liked_videos");'喜欢'
collected = models.ManyToManyField(settings.AUTH_USER_MODEL,
blank=True, related_name="collected_videos")
blank=True, related_name="collected_videos");'收藏'
create_time = models.DateTimeField(auto_now_add=True, blank=True, max_length=20)
objects = VideoQuerySet.as_manager()

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

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

@ -3,7 +3,6 @@ from django.shortcuts import get_object_or_404
from django.views import generic
from django.views.decorators.http import require_http_methods
from helpers import get_page_list, ajax_required
from .forms import CommentForm
from .models import Video, Classification

@ -54,7 +54,7 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
SITE_URL = '127.0.0.1'
SITE_URL = 'https://wowuwua.com'
ROOT_URLCONF = 'videoproject.urls'

Loading…
Cancel
Save