将之前新闻网站django项目的首页、分类页、详情页的数据渲染改成了用vue.js+restful api进行前端渲染
api.py:
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework import status
from django.contrib.auth.models import User
from .models import *
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from rest_framework.decorators import api_view, authentication_classes
from rest_framework.authentication import TokenAuthentication
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
depth = 1
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = '__all__'
depth = 1
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','profile','username')
depth = 1
class CommentSerializer(serializers.ModelSerializer):
belong_user = UserSerializer()
class Meta:
model = Comment
fields = '__all__'
depth = 1
@api_view(['GET'])
def api_index(request): #首页api
cates = Category.objects.all().order_by("-id") #分类列表
cates = CategorySerializer(cates,many=True)
todaynew_big = Best.objects.filter(select_reason="今日新闻")[0].select_article #取出一篇今日新闻作为大标题
todaynew_big = ArticleSerializer(todaynew_big)
todaynew = Best.objects.filter(select_reason="今日新闻")[:3]
todaynew_top3 = [i.select_article for i in todaynew] #取出三篇今日新闻
todaynew_top3 = ArticleSerializer(todaynew_top3,many=True)
index_recommend = Best.objects.filter(select_reason="首页推荐")[:4]
index_recommendlist = [i.select_article for i in index_recommend] #取出四篇首页推荐
index_recommendlist = ArticleSerializer(index_recommendlist,many=True)
editor_recommendtop3 = Best.objects.filter(select_reason="编辑推荐")[:3]
editor_recommendtop3list = [i.select_article for i in editor_recommendtop3] #取出三篇编辑推荐作为大标题
editor_recommendtop3list = ArticleSerializer(editor_recommendtop3list,many=True)
editor_recommend = Best.objects.filter(select_reason="编辑推荐")[3:10]
editor_recommendlist = [i.select_article for i in editor_recommend] #再取出七篇编辑推荐
editor_recommendlist = ArticleSerializer(editor_recommendlist,many=True)
article_list = Article.objects.all().order_by("-publish_time") #取出所有文章
pagerobot = Paginator(article_list,5) #创建分页器,每页限定五篇文章
page_num = request.GET.get("page") #取到当前页数
try:
article_list = pagerobot.page(page_num) #一般情况下返回当前页码下的文章
except EmptyPage:
article_list = pagerobot.page(pagerobot.num_pages) #如果不存在该业,返回最后一页
except PageNotAnInteger:
article_list = pagerobot.page(1) #如果页码不是一个整数,返回第一页
pages = len(article_list.paginator.page_range) #取总页数
article_list = ArticleSerializer(article_list,many=True)
context={}
context={
"cates":cates.data,
"todaynew_big":todaynew_big.data,
"todaynew_top3":todaynew_top3.data,
"index_recommendlist":index_recommendlist.data,
"editor_recommendtop3list":editor_recommendtop3list.data,
"editor_recommendlist":editor_recommendlist.data,
"pages":pages,
"article_list":article_list.data
}
return Response(context)
@api_view(['GET'])
def api_category(request,cate_id):
cates = Category.objects.all().order_by("-id") #分类列表
cates = CategorySerializer(cates,many=True)
editor_recommendtop3 = Best.objects.filter(select_reason="编辑推荐")[:3]
editor_recommendtop3list = [i.select_article for i in editor_recommendtop3] #取出三篇编辑推荐作为大标题
editor_recommendtop3list = ArticleSerializer(editor_recommendtop3list,many=True)
editor_recommend = Best.objects.filter(select_reason="编辑推荐")[3:10]
editor_recommendlist = [i.select_article for i in editor_recommend] #再取出七篇编辑推荐
editor_recommendlist = ArticleSerializer(editor_recommendlist,many=True)
article_list = Article.objects.filter(category=int(cate_id)).order_by("-publish_time") #取出当前目录下的所有文章
print(article_list[0].category)
pagerobot = Paginator(article_list,5) #创建分页器,每页限定五篇文章
page_num = request.GET.get("page") #取到当前页数
try:
article_list = pagerobot.page(page_num) #一般情况下返回当前页码下的文章
except EmptyPage:
article_list = pagerobot.page(pagerobot.num_pages) #如果不存在该业,返回最后一页
except PageNotAnInteger:
article_list = pagerobot.page(1) #如果页码不是一个整数,返回第一页
pages = len(article_list.paginator.page_range) #取总页数
article_list = ArticleSerializer(article_list,many=True)
context={}
context={
"cates":cates.data,
"editor_recommendtop3list":editor_recommendtop3list.data,
"editor_recommendlist":editor_recommendlist.data,
"pages":pages,
"article_list":article_list.data
}
return Response(context)
@api_view(['GET','POST'])
@authentication_classes((TokenAuthentication,))
def api_detail(request,article_id):
if request.method == 'POST':
article_id = request.POST.get('article_id')
current_article = Article.objects.get(id=article_id)
current_user = User.objects.get(id=request.user.id)
created = request.POST.get('created')
words = request.POST.get('words')
newcomment = Comment(belong_article=current_article,belong_user=current_user,created=created,words=words)
newcomment.save()
return Response(status=status.HTTP_201_CREATED)
cates = Category.objects.all().order_by("-id") #分类列表
cates = CategorySerializer(cates,many=True)
editor_recommendtop3 = Best.objects.filter(select_reason="编辑推荐")[:3]
editor_recommendtop3list = [i.select_article for i in editor_recommendtop3] #取出三篇编辑推荐作为大标题
editor_recommendtop3list = ArticleSerializer(editor_recommendtop3list,many=True)
editor_recommend = Best.objects.filter(select_reason="编辑推荐")[3:10]
editor_recommendlist = [i.select_article for i in editor_recommend] #再取出七篇编辑推荐
editor_recommendlist = ArticleSerializer(editor_recommendlist,many=True)
article = Article.objects.get(id=article_id)
comments = Comment.objects.filter(belong_article_id=article_id)
comments = CommentSerializer(comments,many=True)
article = ArticleSerializer(article)
context ={}
context ={
"cates":cates.data,
"editor_recommendtop3list":editor_recommendtop3list.data,
"editor_recommendlist":editor_recommendlist.data,
"article":article.data,
"comments":comments.data,
}
return Response(context)
index.html:
<!DOCTYPE html>
{% load staticfiles %}
<html>
<head>
<meta charset="utf-8">
<title>首页</title>
<link rel="stylesheet" href="{% static 'css/semantic.css' %}" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="{% static 'css/index.css' %}" media="screen" title="no title" charset="utf-8">
<script src="/static/js/vue1.js"></script>
<script src="/static/js/reqwest.js"></script>
</script>
</head>
<body id="app">
<div class="ui red basic segment topmenu">
<div class="ui borderless menu container" style="border:0;box-shadow:none;">
<div class="header item" style="margin-right:10px;">
<div class="ui image">
<img src="{%static 'images/index/zhiribao.png' %}" alt="" />
</div>
</div>
<div class="item" style="margin-right:10px;">
<a href="{% url 'index' %}">首页</a>
</div>
{% verbatim %}
<div v-for="cate in cates" class="item" style="margin-right:10px;">
<a href="/category/{{cate.id}}">{{cate.name}}</a>
</div>
{% endverbatim %}
<div class="right menu login">
{% if request.user.is_authenticated %}
<div class="item">
<a href="{% url 'profile' %}"><div class="ui image">
<img src="/upload/{{ request.user.profile.avatar }}" style="height:26px;24px;" alt="" />
</div>
<p style="margin-right:10px;margin-top:6px;color:black;">{{ request.user.username }}</p>
</a>
</div>
<div class="item">
<a href="{% url "logout" %}">
退出
</a>
</div>
{% else %}
<div class="item">
<a href="{% url 'login' %}"><div class="ui image">
<img src="{% static 'images/index/login.png' %}" alt="" />
</div>
<p style="margin-right:10px;margin-top:6px;color:black;">登录</p>
</a>
</div>
<div class="item">
<a href="{% url 'register' %}"> <div class="ui image">
<img src="{% static 'images/index/register.png' %}" alt="" />
</div>
<p style="color:black;">注册</p>
</a>
</div>
{% endif %}
</div>
</div>
</div>
<div class="ui basic segment body container">
<div class="ui basic segment container topcontent" style="border:none">
<div class="ui horizontal basic segments" style="border:none;">
{% verbatim %}
<div class="ui basic segment topleft" style="background: url('{{todaynew_big.image}}');background-size:cover;background-repeat: no-repeat;" >
<a href="#" class="ui circular red button" style="80px;height:35px;padding:0px;padding-top:10px;">今日热闻</a>
<div class="ui basic segment title">
<a href="/detail/{{todaynew_big.id}}"><p style="color:#fff;font-size:28px;margin-left:8px;">{{todaynew_big.title}}</p></a>
</div>
</div>
{% endverbatim %}
<div class="ui basic segment topright" >
{% verbatim %}
<div v-for="todaynew in todaynew_top3" class="ui segment" style="border:solid red 1px;">
<a href="/detail/{{todaynew.id}}">
<p>
{{todaynew.title}}
</p>
</a>
<span style="color:rgb(195, 200, 194)">{{todaynew.publish_time | date:"Y-m-d"}}</span>
</div>
{% endverbatim %}
</div>
</div>
</div>
<div class="ui grid container">
{% verbatim %}
<div v-for="index_recommend in index_recommendlist"class="four wide column">
<a href="/detail/{{index_recommend.id}}">
<div class="ui basic segment" style="background:url('{{index_recommend.image}}');background-size: cover;
background-repeat: no-repeat;">
<div class="ui basic segment title">
<p style="color:#fff;font-size:18px;margin-left:0px;">{{index_recommend.title}}</p>
</div>
</a>
</div>
</div>
{% endverbatim %}
</div>
<div class="ui horizontal basic segments bottomcontent">
<div class="ui segment bottomleft" style="border:none;box-shadow:none;">
{% verbatim %}
<div v-for="article in article_list" class="ui segment article" style="border:none;box-shadow:none;">
<div class="ui image">
<img src="{{article.image}}" alt="" />
</div>
<div class="ui segment articlecontent" style="border:none;box-shadow:none;">
<a href="/detail/{{article.id}}"><h3><b>{{article.title}}</b></h3></a>
<p>
{{article.abstract}}
</p>
<span style="color:rgb(206, 208, 204);position:absolute;transform:translate(0,100%);bottom:10%">{{article.publish_time | date:"Y-m-d"}}</span>
</div>
</div>
{% endverbatim %}
<div class="ui pagination menu" style="margin-left:50%;transform:translate(-50%,0%);">
{% verbatim %}
<a v-on:click="update_page(this_page-1)" class="{{ previous_disabled_status() }} item"><i class="icon {{ leftcaret_color() }} left caret"></i></a>
<a v-on:click="update_page(pagenumber+1)" v-for="pagenumber in pages" class="{{ pagenum_active_status(pagenumber+1) }} item" style="{{ pagenum_color(pagenumber+1) }}">
{{ pagenumber+1 }}
</a>
<a v-on:click="update_page(this_page+1)" class="{{ next_disabled_status() }} item"><i class="icon {{ rightcaret_color() }} right caret"></i></a>
{% endverbatim %}
</div>
</div>
<div class="ui segment bottomright" style="border:none;box-shadow:none;">
<div class="ui red segment best">
<h4 class="ui center aligned header"><b>编辑推荐</b></h4>
{% verbatim %}
<div v-for="editor_recommendtop3 in editor_recommendtop3list" class="ui segment top3" style="background:url('{{editor_recommendtop3.image}}');
background-size:cover;background-repeat:no-repeat;border-radius:0;">
<div class="sidebutton">
<img src="/static/images/index/redtag.png" alt="" />
<p>Top{{ $index+1 }}</p>
</div>
<div class="ui basic segment title" style="height:40px;padding-top:2px;">
<p style="font-size:14px;margin-left:0px;"><a href="/detail/{{editor_recommendtop3.id}}" style="color:#fff;">{{editor_recommendtop3.title}}</a></p>
</div>
</div>
{% endverbatim %}
{% verbatim %}
<div v-for="editor_recommend in editor_recommendlist" class="ui segment bestlast">
<img src="/static/images/index/Triangle.png" alt="" />
<p>
<a href="/detail/{{editor_recommend.id}}">
{{editor_recommend.title}}
</a>
</p>
<span>{{editor_recommend.publish_time | date:"Y-m-d"}}</span>
</div>
{% endverbatim %}
<div class="ui image">
<img src="{% static 'images/index/ad.png' %}" alt="" style="300px;"/>
</div>
</div>
</div>
</div>
</div>
<div class="ui basic segment bottomblack">
<div class="ui image">
<img src="{% static 'images/index/white_zhiribao.png' %}" alt="" />
</div>
<p style="color:red;margin-top:50px;font-size:20px;">
关于我们<span style="color:rgb(143, 143, 143)">|</span>加入我们<span style="color:rgb(143, 143, 143)">|</span>联系我们|寻求报道
</p>
<p style="color:white;font-size:20px;">
反馈建议:<span style="color:red;">124608760@qq.com</span>
</p>
<div class="ui basic segment wechat">
<img src="{% static 'images/index/qrcode.png' %}" style="margin-left:38px;"/>
<h2 class="ui header" style="color:rgb(255, 255, 255);margin-left:20px;">扫码关注微信号</h2>
</div>
<button type="button" name="button" class="ui circular red button backtotop">
<img src="{% static 'images/index/upicon.png' %}" style="position:absolute;left:18%;top:10%;">
<img src="{% static 'images/index/TOP.png' %}" style="position:absolute;left:18%;bottom:28%;">
</button>
</div>
<div class="ui basic segment bottomwhite">
<p>
Designed by Mugglecoding
</p>
<p>
Developed by XYX
</p>
<p style="position:absolute;right:250px;top:40px;">
京ICP备123878345号
</p>
</div>
<script>
var vm = new Vue(
{
el:"#app",
data:{
"cates":[],
"todaynew_big":"",
"todaynew_top3":[],
"index_recommendlist":[],
"editor_recommendtop3list":[],
"editor_recommendlist":[],
"pages":"",
"this_page":1,
"article_list":[]
},
methods:{
leftcaret_color:function(){
if(this.this_page > 1){
return "red"
}
else{
return ""
}
},
rightcaret_color:function(){
if(this.this_page < this.pages){
return "red"
}
else{
return ""
}
},
previous_disabled_status:function(){
if(this.this_page > 1){
return ""
}
else{
return "disabled"
}
},
next_disabled_status:function(){
if(this.this_page < this.pages){
return ""
}
else{
return "disabled"
}
},
pagenum_active_status:function(page){
if(this.this_page == page){
return "active"
}
else{
return ""
}
},
pagenum_color:function(page){
if(this.this_page == page){
return "background-color: red; color:white"
}
else{
return ""
}
},
update_page:function(page){
var self = this;
if(page > this.pages){
page = this.pages;
};
if(page < 1){
page = 1;
}
this.this_page = page;
reqwest({
url:'/api/index/?page='+page,
type:'json',
method:'get',
success:function(resp){
self.article_list = resp.article_list;
}
})
},
getdata:function(){
var self = this;
reqwest({
url:'/api/index/?page='+self.this_page,
type:'json',
method:'get',
success:function(resp){
console.log(resp);
self.cates = resp.cates;
self.todaynew_big = resp.todaynew_big;
self.todaynew_top3 = resp.todaynew_top3;
self.index_recommendlist = resp.index_recommendlist;
self.editor_recommendtop3list = resp.editor_recommendtop3list;
self.editor_recommendlist = resp.editor_recommendlist;
self.pages = resp.pages;
self.article_list = resp.article_list;
},
})
},
},
ready:function(){
this.getdata();
}
}
)
</script>
</body>
</html>
category.html:
<!DOCTYPE html>
{% load staticfiles %}
<html>
<head>
<meta charset="utf-8">
<title>分类页</title>
<link rel="stylesheet" href="{% static 'css/semantic.css' %}" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="{% static 'css/category.css' %}" media="screen" title="no title" charset="utf-8">
<script src="/static/js/vue1.js"></script>
<script src="/static/js/reqwest.js"></script>
</head>
<body id="app">
<div class="ui red basic segment topmenu">
<div class="ui borderless menu container" style="border:0;box-shadow:none;">
<div class="header item" style="margin-right:10px;">
<div class="ui image">
<img src="{%static 'images/index/zhiribao.png' %}" alt="" />
</div>
</div>
<div class="item" style="margin-right:10px;">
<a href="{% url 'index' %}">首页</a>
</div>
{% verbatim %}
<div v-for="cate in cates" class="item" style="margin-right:10px;">
<a href="/category/{{cate.id}}">{{cate.name}}</a>
</div>
{% endverbatim %}
<div class="right menu login">
{% if request.user.is_authenticated %}
<div class="item">
<a href="{% url 'profile' %}"><div class="ui image">
<img src="/upload/{{ request.user.profile.avatar }}" style="height:26px;24px;" alt="" />
</div>
<p style="margin-right:10px;margin-top:6px;color:black;">{{ request.user.username }}</p>
</a>
</div>
<div class="item">
<a href="{% url "logout" %}">
退出
</a>
</div>
{% else %}
<div class="item">
<a href="{% url 'login' %}"><div class="ui image">
<img src="{% static 'images/index/login.png' %}" alt="" />
</div>
<p style="margin-right:10px;margin-top:6px;color:black;">登录</p>
</a>
</div>
<div class="item">
<a href="{% url 'register' %}"> <div class="ui image">
<img src="{% static 'images/index/register.png' %}" alt="" />
</div>
<p style="color:black;">注册</p>
</a>
</div>
{% endif %}
</div>
</div>
</div>
<div class="ui basic segment container">
<div class="ui horizontal basic segments bodycontent">
<div class="ui segment bodyleft" style="border:none;box-shadow:none;">
{% verbatim %}
<div v-for="article in article_list" class="ui segment article" style="border:none;box-shadow:none;">
<div class="ui image">
<img src="{{article.image}}" alt="" />
</div>
<div class="ui segment articlecontent" style="border:none;box-shadow:none;">
<a href="/detail/{{article.id}}"><h3><b>{{article.title}}</b></h3></a>
<p>
{{article.abstract}}
</p>
<span style="color:rgb(206, 208, 204);position:absolute;transform:translate(0,100%);bottom:10%">{{article.publish_time | date:"Y-m-d"}}</span>
</div>
</div>
{% endverbatim %}
<div class="ui pagination menu" style="margin-left:50%;transform:translate(-50%,0%);">
{% verbatim %}
<a v-on:click="update_page(this_page-1)" class="{{ previous_disabled_status() }} item"><i class="icon {{ leftcaret_color() }} left caret"></i></a>
<a v-on:click="update_page(pagenumber+1)" v-for="pagenumber in pages" class="{{ pagenum_active_status(pagenumber+1) }} item" style="{{ pagenum_color(pagenumber+1) }}">
{{ pagenumber+1 }}
</a>
<a v-on:click="update_page(this_page+1)" class="{{ next_disabled_status() }} item"><i class="icon {{ rightcaret_color() }} right caret"></i></a>
{% endverbatim %}
</div>
</div>
<div class="ui segment bodyright" style="border:none;box-shadow:none;">
<div class="ui red segment best">
<h4 class="ui center aligned header"><b>编辑推荐</b></h4>
{% verbatim %}
<div v-for="editor_recommendtop3 in editor_recommendtop3list" class="ui segment top3" style="background:url('{{editor_recommendtop3.image}}');
background-size:cover;background-repeat:no-repeat;border-radius:0;">
<div class="sidebutton">
<img src="/static/images/index/redtag.png" alt="" />
<p>Top{{ $index+1 }}</p>
</div>
<div class="ui basic segment title" style="height:40px;padding-top:2px;">
<p style="font-size:14px;margin-left:0px;"><a href="/detail/{{editor_recommendtop3.id}}" style="color:#fff;">{{editor_recommendtop3.title}}</a></p>
</div>
</div>
{% endverbatim %}
{% verbatim %}
<div v-for="editor_recommend in editor_recommendlist" class="ui segment bestlast">
<img src="/static/images/index/Triangle.png" alt="" />
<p>
<a href="/detail/{{editor_recommend.id}}">
{{editor_recommend.title}}
</a>
</p>
<span>{{editor_recommend.publish_time | date:"Y-m-d"}}</span>
</div>
{% endverbatim %}
<div class="ui image">
<img src="{% static 'images/index/ad.png' %}" alt="" style="300px;"/>
</div>
</div>
</div>
</div>
</div>
<div class="ui basic segment bottomblack">
<div class="ui image">
<img src="{% static 'images/index/white_zhiribao.png' %}" alt="" />
</div>
<p style="color:red;margin-top:50px;font-size:20px;">
关于我们<span style="color:rgb(143, 143, 143)">|</span>加入我们<span style="color:rgb(143, 143, 143)">|</span>联系我们|寻求报道
</p>
<p style="color:white;font-size:20px;">
反馈建议:<span style="color:red;">124608760@qq.com</span>
</p>
<div class="ui basic segment wechat">
<img src="{% static 'images/index/qrcode.png' %}" style="margin-left:38px;"/>
<h2 class="ui header" style="color:rgb(255, 255, 255);margin-left:20px;">扫码关注微信号</h2>
</div>
<button type="button" name="button" class="ui circular red button backtotop">
<img src="{% static 'images/index/upicon.png' %}" style="position:absolute;left:18%;top:10%;">
<img src="{% static 'images/index/TOP.png' %}" style="position:absolute;left:18%;bottom:28%;">
</button>
</div>
<div class="ui basic segment bottomwhite">
<p>
Designed by Mugglecoding
</p>
<p>
Developed by XYX
</p>
<p style="position:absolute;right:250px;top:40px;">
京ICP备123878345号
</p>
</div>
<script>
var vm = new Vue(
{
el:"#app",
data:{
"cates":[],
"editor_recommendtop3list":[],
"editor_recommendlist":[],
"pages":"",
"this_page":1,
"article_list":[]
},
methods:{
leftcaret_color:function(){
if(this.this_page > 1){
return "red"
}
else{
return ""
}
},
rightcaret_color:function(){
if(this.this_page < this.pages){
return "red"
}
else{
return ""
}
},
previous_disabled_status:function(){
if(this.this_page > 1){
return ""
}
else{
return "disabled"
}
},
next_disabled_status:function(){
if(this.this_page < this.pages){
return ""
}
else{
return "disabled"
}
},
pagenum_active_status:function(page){
if(this.this_page == page){
return "active"
}
else{
return ""
}
},
pagenum_color:function(page){
if(this.this_page == page){
return "background-color: red; color:white"
}
else{
return ""
}
},
update_page:function(page){
var self = this;
var id = location.href.split("/")[4];
if(page > this.pages){
page = this.pages;
};
if(page < 1){
page = 1;
}
this.this_page = page;
reqwest({
url:'/api/category/' + id +'?page='+self.this_page,
type:'json',
method:'get',
success:function(resp){
self.article_list = resp.article_list;
}
})
},
getdata:function(){
var self = this;
var id = location.href.split("/")[4];
reqwest({
url:'/api/category/' + id +'?page='+self.this_page,
type:'json',
method:'get',
success:function(resp){
console.log(resp);
self.cates = resp.cates;
self.editor_recommendtop3list = resp.editor_recommendtop3list;
self.editor_recommendlist = resp.editor_recommendlist;
self.pages = resp.pages;
self.article_list = resp.article_list;
},
})
},
},
ready:function(){
this.getdata();
}
}
)
</script>
</body>
</html>
detail.html:
<!DOCTYPE html>
{% load staticfiles %}
<html>
<head>
<meta charset="utf-8">
<title>详情页</title>
<link rel="stylesheet" href="{% static 'css/semantic.css' %}" media="screen" title="no title" charset="utf-8">
<link rel="stylesheet" href="{% static 'css/detail.css' %}" media="screen" title="no title" charset="utf-8">
<script src="/static/js/vue1.js"></script>
<script src="/static/js/reqwest.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.1.3/js.cookie.js"></script>
</head>
<body id="app">
<div class="ui red basic segment topmenu">
<div class="ui borderless menu container" style="border:0;box-shadow:none;">
<div class="header item" style="margin-right:10px;">
<div class="ui image">
<img src="{%static 'images/index/zhiribao.png' %}" alt="" />
</div>
</div>
<div class="item" style="margin-right:10px;">
<a href="{% url 'index' %}">首页</a>
</div>
{% verbatim %}
<div v-for="cate in cates" class="item" style="margin-right:10px;">
<a href="/category/{{cate.id}}">{{cate.name}}</a>
</div>
{% endverbatim %}
<div class="right menu login">
{% if request.user.is_authenticated %}
<div class="item">
<a href="{% url 'profile' %}"><div class="ui image">
<img src="/upload/{{ request.user.profile.avatar }}" style="height:26px;24px;" alt="" />
</div>
<p style="margin-right:10px;margin-top:6px;color:black;">{{ request.user.username }}</p>
</a>
</div>
<div class="item">
<a href="{% url "logout" %}">
退出
</a>
</div>
{% else %}
<div class="item">
<a href="{% url 'login' %}"><div class="ui image">
<img src="{% static 'images/index/login.png' %}" alt="" />
</div>
<p style="margin-right:10px;margin-top:6px;color:black;">登录</p>
</a>
</div>
<div class="item">
<a href="{% url 'register' %}"> <div class="ui image">
<img src="{% static 'images/index/register.png' %}" alt="" />
</div>
<p style="color:black;">注册</p>
</a>
</div>
{% endif %}
</div>
</div>
</div>
<div class="ui basic segment container">
<div class="ui horizontal basic segments bodycontent">
<div class="ui segment bodyleft" style="border:none;box-shadow:none;">
{% verbatim %}
<div class="ui basic segment articleimg" style="background:url('{{article.image}}');background-size: cover;
background-repeat: no-repeat;">
<hr>
<div class="image-text" >
{{article.title}}
</div>
<span>图片:Zoommy</span>
</div>
<div class="ui center aligned basic segment abstract">
*** <br>
{{article.abstract}} <br>
***
</div>
<div class="ui basic segment articledetail">
<h1>{{article.title}}</h1>
<p>
<div class="ui mini image" style="position:relative;top:-2px;left:5px;">
<img src="{{article.author_avatar}}" alt="" />
</div>
<span style="font-size:16px;color: #000000;margin-left:10px;"> {{ article.author_name }}</span>
<span style="color:grey;font-size:16px;">{{ article.author_desc }}</span>
<p style="color:#000000;600px;font-size:16px;margin-top:20px;line-height:2;">
{{article.content}}
</p>
<a href="{{article.source_link}}"><span style="border-bottom:1px solid red;font-size:16px;margin-top:50px;margin-left:520px;">查看原文</span></a>
</div>
{% endverbatim %}
<div class="ui basic segment comment">
<p ><b>评论</b></p>
{% verbatim %}
<div v-for="comment in comments" class="comment" style="margin-top:22px;margin-bottom:20px;">
<div class="ui image" style="height:50px;50px;">
<img src="{{ comment.belong_user.profile.avatar }}" style="height:50px;50px;" alt="" />
</div>
<span class="time"> <b style="color:black;">{{comment.belong_user.username}}</b> {{comment.created}}</span>
<span class="black-reply"> {{comment.words}}</span>
</div>
{% endverbatim %}
{% verbatim %}
<form class="ui error form" method="POST" >
<textarea name="comment" rows="8" cols="40" v-model="words"></textarea>
</form>
<button class="ui red button" v-on:click="sendcomment" style="144px;height:49px;position:relative;top:60px;" >
<span style="color: #ffffff;font-size: 20px;font-weight: bold;">写评论</span>
</button>
{% endverbatim %}
</div>
</div>
<div class="ui segment bodyright" style="border:none;box-shadow:none;">
<div class="ui red segment best">
<h4 class="ui center aligned header"><b>编辑推荐</b></h4>
{% for editor_recommendtop3 in editor_recommendtop3list %}
<div class="ui segment top3" style="background:url('/upload/{{editor_recommendtop3.image}}');
background-size:cover;background-repeat:no-repeat;border-radius:0;">
<div class="sidebutton">
<img src="{% static 'images/index/redtag.png' %}" alt="" />
<p>Top{{ forloop.counter }}</p>
</div>
<div class="ui basic segment title" style="height:40px;padding-top:2px;">
<p style="font-size:14px;margin-left:0px;"><a href="/detail/{{editor_recommendtop3.id}}" style="color:#fff;">{{editor_recommendtop3.title}}</a></p>
</div>
</div>
{% endfor %}
{% for editor_recommend in editor_recommendlist %}
<div class="ui segment bestlast">
<img src="{% static 'images/index/Triangle.png' %}" alt="" />
<p>
<a href="/detail/{{editor_recommend.id}}">
{{editor_recommend.title}}
</a>
</p>
<span>{{editor_recommend.publish_time | date:"Y-m-d"}}</span>
</div>
{% endfor %}
<div class="ui image">
<img src="{% static 'images/index/ad.png' %}" alt="" style="300px;"/>
</div>
</div>
</div>
</div>
</div>
<div class="ui basic segment bottomblack">
<div class="ui image">
<img src="{% static 'images/index/white_zhiribao.png' %}" alt="" />
</div>
<p style="color:red;margin-top:50px;font-size:20px;">
关于我们<span style="color:rgb(143, 143, 143)">|</span>加入我们<span style="color:rgb(143, 143, 143)">|</span>联系我们|寻求报道
</p>
<p style="color:white;font-size:20px;">
反馈建议:<span style="color:red;">124608760@qq.com</span>
</p>
<div class="ui basic segment wechat">
<img src="{% static 'images/index/qrcode.png' %}" style="margin-left:38px;"/>
<h2 class="ui header" style="color:rgb(255, 255, 255);margin-left:20px;">扫码关注微信号</h2>
</div>
<button type="button" name="button" class="ui circular red button backtotop">
<img src="{% static 'images/index/upicon.png' %}" style="position:absolute;left:18%;top:10%;">
<img src="{% static 'images/index/TOP.png' %}" style="position:absolute;left:18%;bottom:28%;">
</button>
</div>
<div class="ui basic segment bottomwhite">
<p>
Designed by Mugglecoding
</p>
<p>
Developed by XYX
</p>
<p style="position:absolute;right:250px;top:40px;">
京ICP备123878345号
</p>
</div>
<script>
var vm = new Vue(
{
el:"#app",
data:{
"cates":[],
"editor_recommendtop3list":[],
"editor_recommendlist":[],
"article":[],
"comments":[],
"article_id":'',
"created":'',
"words":'',
},
methods:{
sendcomment:function(){
var self = this;
var id = location.href.split("/")[4];
var datenow = new Date();
reqwest({
url:'/api/detail/'+ id +'/',
type:'json',
method:'post',
headers:Cookies.get('token')? {'Authorization': 'Token ' + Cookies.get('token')}:{},
data:{
article_id:id,
created:datenow.toISOString(),
words:self.words
},
success:function(resp){
location.reload();
}
})
},
getdata:function(){
var self = this;
var id = location.href.split("/")[4];
reqwest({
url:'/api/detail/'+id,
type:'json',
method:'get',
success:function(resp){
console.log(resp);
self.cates = resp.cates;
self.editor_recommendtop3list = resp.editor_recommendtop3list;
self.editor_recommendlist = resp.editor_recommendlist;
self.article = resp.article;
self.comments = resp.comments;
},
})
},
},
ready:function(){
this.getdata();
}
}
)
</script>
</body>
</html>
urls.py:
from django.conf.urls import url
from django.contrib import admin
from newswebsite.views import *
from newswebsite.api import *
from django.conf import settings
from django.conf.urls.static import static
from rest_framework.authtoken import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', index, name='index'),
url(r'^category/(?P<cate_id>d+)/$', category, name='category'),
url(r'^detail/(?P<article_id>d+)/$', detail, name='detail'),
url(r'^login/', login, name='login'),
url(r'^register/', register, name='register'),
url(r'^logout/', logout, name='logout'),
url(r'^profile/', profile, name='profile'),
#api
url(r'^api/index/', api_index, name='api_index'),
url(r'^api/category/(?P<cate_id>d+)/$', api_category, name='api_category'),
url(r'^api/detail/(?P<article_id>d+)/$', api_detail, name='api_detail'),
url(r'^api/token-auth/$', views.obtain_auth_token),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
view.py:
from django.contrib.auth.decorators import login_required
from django.shortcuts import render,Http404, redirect, HttpResponse
from django.contrib.auth import authenticate,login as user_login,logout as user_logout
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from newswebsite.models import *
from newswebsite.forms import *
from rest_framework.authtoken.models import Token
# Create your views here.
def index(request):
return render(request,'index.html')
def category(request,cate_id):
return render(request,'category.html')
def detail(request,article_id):
if not isinstance(request.user, User):
return render(request, 'detail.html')
token, created = Token.objects.get_or_create(user=request.user) #创建登录用户的token并存到cookie中
response = render(request, 'detail.html')
response.set_cookie(key='token',value=token.key)
return response
def login(request):
if request.method == 'GET':
form = LoginForm()
if request.method == 'POST':
form = LoginForm(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:
user_login(request,user) #由于login方法和我自定义的login视图重名,这里将django.contrib.auth中的login方法重命名为user_login导入
return redirect(to='index')
else:
return HttpResponse('用户名不存在或用户名密码错误')
context={}
context['form'] = form
return render(request,'login.html',context=context)
def register(request):
if request.method == 'GET':
form = RegisterForm()
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get("username")
email = form.cleaned_data.get("email")
password = form.cleaned_data.get("password")
user = User(username=username,email=email)
user.set_password(password)
user.save() #创建用户保存
userprofile = UserProfile(belong_to=user,avatar='avatar/avatar.png')
userprofile.save() #创建该用户的资料
return redirect(to='login')
context={}
context['form']=form
return render(request,'register.html',context=context)
@login_required(login_url='login') #未登录则跳转到登录页面
def profile(request):
if request.method == 'GET':
form = EditForm(initial={'username':request.user.username,'email':request.user.email})
if request.method == 'POST':
form = EditForm(request.POST,request.FILES)
if form.is_valid():
user = request.user
email = form.cleaned_data.get("email")
password = form.cleaned_data.get("password")
avatar = form.cleaned_data.get("avatar")
user.email = email
if avatar:
user_profile = UserProfile.objects.get(belong_to=user)
user_profile.avatar = avatar
user_profile.save() #如果有上传头像,替换用户的头像
user.set_password(password)
user.save()
return redirect(to='login')
context={}
context['form']=form
return render(request,'profile.html',context=context)
def logout(request):
user_logout(request)
return redirect(to='login')