從本講起,咱們會講到我的菜單中另外兩個比較重要的功能,「個人收藏」與「個人喜歡」。感興趣的同窗能夠點擊網站的右上角,便可彈出我的菜單,你就能看到「個人收藏」與「個人喜歡」了。經過學習這兩個功能,咱們會加深對django中通用視圖類的理解與應用。html
Demo預覽python
咱們先來討論模型,咱們分析一下,我收藏的視頻與我喜歡的視頻,其中的視頻都是屬於video模型,所以咱們應該在video模型上進行修改。由於是個人收藏、個人喜歡,都是與我關聯,又由於,我能夠收藏多個視頻,視頻也能夠被多個用戶收藏,因此用戶與視頻是屬於多對多的關係。因此咱們在video模型上添加兩個字段liked和collected,分別對應我喜歡和我收藏。代碼以下django
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)
複製代碼
能夠看出liked和collected字段都是屬於ManyToManyField類型,表示視頻與用戶是多對多的關係。並分別設置它們的別名爲"liked_videos"和"collected_videos",有django基礎的同窗應該明白,經過別名也能夠訪問到數據。bash
下面咱們來添加二者的路由,添加在users/urls.py下面。ide
path('<int:pk>/collect_videos/', views.CollectListView.as_view(), name='collect_videos'),
path('<int:pk>/like_videos/', views.LikeListView.as_view(), name='like_videos'),
複製代碼
其中,個人收藏的視圖類是CollectListView,個人喜歡的視圖類是LikeListView。咱們先來實現CollectListView函數
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
複製代碼
與首頁展現的功能相似,這裏一樣繼承了ListView通用視圖類。並使用了公共函數get_page_list對數據進行分頁。在獲取收藏數據列表時,咱們用的是user.collected_videos.all(),其中collected_videos就是前面定義的別名。 並經過配置template_name將數據傳遞給模板文件users/collect_videos.html。學習
模板文件關鍵代碼網站
<h3 class="ui header">個人收藏</h3>
<div class="ui unstackable items">
{% for item in video_list %}
<div class="item">
<div class="ui tiny image">
{% thumbnail item.cover "300x200" crop="center" as im %}
<img class="ui image" src="{{ im.url }}">
{% empty %}
{% endthumbnail %}
</div>
<div class="middle aligned content">
<a class="header" href="{% url 'video:detail' item.pk %}">{{ item.title }}</a>
</div>
</div>
{% empty %}
<h3>暫無數據</h3>
{% endfor %}
</div>
{% include "base/page_nav.html" %}
複製代碼
最終展現效果ui
下面來開發個人喜歡功能url
該功能與個人收藏功能相似。由於前面已經添加了like_videos路由,咱們直接寫LikeListView的代碼
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):
user = get_object_or_404(User, pk=self.kwargs.get('pk'))
videos = user.liked_videos.all()
return videos
複製代碼
與個人收藏的模式如出一轍,一樣是繼承ListView並設置相關model與template_name變量。最終經過users/like_videos.html來渲染。
like_videos.html關鍵代碼
<h3 class="ui header">個人喜歡</h3>
<div class="ui unstackable items">
{% for item in video_list %}
<div class="item">
<div class="ui tiny image">
{% thumbnail item.cover "300x200" crop="center" as im %}
<img class="ui image" src="{{ im.url }}">
{% empty %}
{% endthumbnail %}
</div>
<div class="middle aligned content">
<a class="header" href="{% url 'video:detail' item.pk %}">{{ item.title }}</a>
</div>
</div>
{% empty %}
<h3>暫無數據</h3>
{% endfor %}
</div>
{% include "base/page_nav.html" %}
複製代碼
最終展現效果