美文网首页Django 学习笔记
一个复杂的Django Model 和View 定义的案例

一个复杂的Django Model 和View 定义的案例

作者: whong736 | 来源:发表于2017-08-30 07:41 被阅读19次

Model定义


#coding:utf-8
from django.db import models
from django.conf import settings

#用来修改admin中显示的app名称,因为admin app 名称是用 str.title()显示的,所以修改str类的title方法就可以实现.
class string_with_title(str):
    def __new__(cls, value, title):
        instance = str.__new__(cls, value)
        instance._title = title
        return instance

    def title(self):
        return self._title

    __copy__ = lambda self: self
    __deepcopy__ = lambda self, memodict: self

# Create your models here.
STATUS = {
        0: u'正常',
        1: u'草稿',
        2: u'删除',
}

#资讯来源
NEWS = {
        0: u'oschina',
        1: u'chiphell',
        2: u'freebuf',
        3: u'cnBeta',
}


class Nav(models.Model):
    name = models.CharField(max_length=40,verbose_name=u'导航条内容')
    url = models.CharField(max_length=200,blank=True,null=True,verbose_name=u'指向地址')

    status = models.IntegerField(default=0,choices=STATUS.items(),verbose_name='状态')
    create_time = models.DateTimeField(u'创建时间',auto_now_add=True)

    class Meta:
        verbose_name_plural = verbose_name = u"导航条"
        ordering = ['-create_time']
        app_label = string_with_title('blog',u"博客管理")

    def __unicode__(self):
        return self.name




class Category(models.Model):
    name = models.CharField(max_length=40,verbose_name=u'名称')
    parent = models.ForeignKey('self',default=None,blank=True,null=True,verbose_name=u'上级分类')
    rank = models.IntegerField(default=0,verbose_name=u'排序')
    status = models.IntegerField(default=0,choices=STATUS.items(),verbose_name='状态')

    create_time = models.DateTimeField(u'创建时间',auto_now_add=True)

    class Meta:
        verbose_name_plural = verbose_name = u'分类'
        ordering = ['rank','-create_time']
        app_label = string_with_title('blog',u"博客管理")

    
    def __unicode__(self):
        if self.parent:
            return '%s-->%s' % (self.parent,self.name)
        else:
            return '%s' % (self.name)


class Article(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL,verbose_name=u'作者')
    category = models.ForeignKey(Category,verbose_name=u'分类')
    title = models.CharField(max_length=100,verbose_name=u'标题')
    en_title = models.CharField(max_length=100,verbose_name=u'英文标题')
    img = models.CharField(max_length=200,default='/static/img/article/default.jpg')
    tags = models.CharField(max_length=200,null=True,blank=True,verbose_name=u'标签',help_text=u'用逗号分隔')
    summary = models.TextField(verbose_name=u'摘要')
    content = models.TextField(verbose_name=u'正文')
    
    view_times = models.IntegerField(default=0)
    zan_times = models.IntegerField(default=0)

    is_top = models.BooleanField(default=False,verbose_name=u'置顶')
    rank = models.IntegerField(default=0,verbose_name=u'排序')
    status = models.IntegerField(default=0,choices=STATUS.items(),verbose_name='状态')


    pub_time = models.DateTimeField(default=False,verbose_name=u'发布时间')
    create_time = models.DateTimeField(u'创建时间',auto_now_add=True)
    update_time = models.DateTimeField(u'更新时间',auto_now=True)

    def get_tags(self):
        return self.tags.split(',')
    
    class Meta:
        verbose_name_plural = verbose_name = u'文章'
        ordering = ['rank','-is_top','-pub_time','-create_time']
        app_label = string_with_title('blog',u"博客管理")
    
    def __unicode__(self):
            return self.title


class Column(models.Model):
    name = models.CharField(max_length=40,verbose_name=u'专栏内容')
    summary = models.TextField(verbose_name=u'专栏摘要')
    article = models.ManyToManyField(Article,verbose_name=u'文章')
    status = models.IntegerField(default=0,choices=STATUS.items(),verbose_name='状态')
    create_time = models.DateTimeField(u'创建时间',auto_now_add=True)

    class Meta:
        verbose_name_plural = verbose_name = u'专栏'
        ordering = ['-create_time']
        app_label = string_with_title('blog',u"博客管理")

    def __unicode__(self):
        return self.name


class Carousel(models.Model):
    title = models.CharField(max_length=100,verbose_name=u'标题')
    summary = models.TextField(blank=True,null=True,verbose_name=u'摘要')
    img = models.CharField(max_length=200,verbose_name=u'轮播图片',default='/static/img/carousel/default.jpg')
    article = models.ForeignKey(Article,verbose_name=u'文章')
    create_time = models.DateTimeField(u'创建时间',auto_now_add=True)
    class Meta:
        verbose_name_plural = verbose_name = u'轮播'
        ordering = ['-create_time']
        app_label = string_with_title('blog',u"博客管理")


class News(models.Model):
    title = models.CharField(max_length=100,verbose_name=u'标题')
    summary = models.TextField(verbose_name=u'摘要')
    news_from = models.IntegerField(default=0,choices=NEWS.items(),verbose_name='来源')
    url = models.CharField(max_length=200,verbose_name=u'源地址')

    create_time = models.DateTimeField(u'创建时间',auto_now_add=True)
    pub_time = models.DateTimeField(default=False,verbose_name=u'发布时间')
   
    
    class Meta:
        verbose_name_plural = verbose_name = u'资讯'
        ordering = ['-title']
        app_label = string_with_title('blog',u"博客管理")

View定义

#coding:utf-8
from django import template
from django import forms
from django.http import HttpResponse,Http404
from django.shortcuts import render,render_to_response
from django.template import Context,loader
from django.views.generic import View,TemplateView,ListView,DetailView
from django.db.models import Q
from django.core.cache import caches
from django.core.exceptions import PermissionDenied
from django.contrib import auth
from django.contrib.auth.forms import PasswordChangeForm,SetPasswordForm
from django.contrib.auth.tokens import default_token_generator
from blog.models import Article,Category,Carousel,Column,Nav,News
from vmaig_comments.models import Comment
from vmaig_auth.models import VmaigUser
from vmaig_auth.forms import VmaigUserCreationForm,VmaigPasswordRestForm
from vmaig_blog.settings import PAGE_NUM
import datetime,time
import json
import logging

#缓存
try:
    cache = caches['memcache']
except ImportError as e:
    cache = caches['default']

#logger
logger = logging.getLogger(__name__)


class BaseMixin(object):
    
    def get_context_data(self,*args,**kwargs):
        context = super(BaseMixin,self).get_context_data(**kwargs)
        try:
            #热门文章
            context['hot_article_list'] = Article.objects.order_by("-view_times")[0:10]
            #导航条
            context['nav_list'] =  Nav.objects.filter(status=0)
            #最新评论
            context['latest_comment_list'] = Comment.objects.order_by("-create_time")[0:10]

        except Exception as e:
            logger.error(u'[BaseMixin]加载基本信息出错')

        return context


class IndexView(BaseMixin,ListView):
    template_name = 'blog/index.html'
    context_object_name = 'article_list'
    paginate_by = PAGE_NUM #分页--每页的数目
    
    def get_context_data(self,**kwargs):
        #轮播
        kwargs['carousel_page_list'] = Carousel.objects.all()
        return super(IndexView,self).get_context_data(**kwargs)

    def get_queryset(self):
        article_list = Article.objects.filter(status=0)
        return article_list
    

class ArticleView(BaseMixin,DetailView):
    queryset = Article.objects.filter(status=0)
    template_name = 'blog/article.html'
    context_object_name = 'article'
    slug_field = 'en_title'
    
    def get(self,request,*args,**kwargs):
        #统计文章的访问访问次数
        if 'HTTP_X_FORWARDED_FOR' in request.META:
            ip = request.META['HTTP_X_FORWARDED_FOR']
        else:
            ip = request.META['REMOTE_ADDR']
        self.cur_user_ip = ip

        en_title = self.kwargs.get('slug')
        #获取15*60s时间内访问过这篇文章的所有ip
        visited_ips = cache.get(en_title,[])
        
        #如果ip不存在就把文章的浏览次数+1
        if ip not in visited_ips:
            try:
                article = self.queryset.get(en_title=en_title)
            except Article.DoesNotExist:
                logger.error(u'[ArticleView]访问不存在的文章:[%s]' % en_title)
                raise Http404
            else:
                article.view_times += 1
                article.save()
                visited_ips.append(ip)

            #更新缓存
            cache.set(en_title,visited_ips,15*60)

        return super(ArticleView,self).get(request,*args,**kwargs)


    def get_context_data(self,**kwargs):
        #评论
        en_title = self.kwargs.get('slug','')
        kwargs['comment_list'] = self.queryset.get(en_title=en_title).comment_set.all()
        return super(ArticleView,self).get_context_data(**kwargs)


class AllView(BaseMixin,ListView):
    template_name = 'blog/all.html'
    context_object_name = 'article_list'

    def get_context_data(self,**kwargs):
        kwargs['category_list'] = Category.objects.all()
        kwargs['PAGE_NUM'] = PAGE_NUM
        return super(AllView,self).get_context_data(**kwargs)

    def get_queryset(self):
        article_list = Article.objects.filter(status=0)[0:PAGE_NUM]
        return article_list

    def post(self, request, *args, **kwargs):
        val = self.request.POST.get("val","")
        sort = self.request.POST.get("sort","time")
        start = self.request.POST.get("start",0)
        end = self.request.POST.get("end",PAGE_NUM)

        start = int(start)
        end = int(end)

        if sort == "time":
            sort = "-pub_time"
        elif sort == "recommend":
            sort = "-view_times"
        else:
            sort = "-pub_time"

        if val == "all":
            article_list = Article.objects.filter(status=0).order_by(sort)[start:end+1]
        else:
            try:
                article_list = Category.objects.get(name=val).article_set.filter(status=0).order_by(sort)[start:end+1]
            except Category.DoesNotExist:
                logger.error(u'[AllView]此分类不存在:[%s]' % val)
                raise PermissionDenied

        isend = len(article_list) != (end-start+1)

        article_list = article_list[0:end-start]

        html = ""
        for article in article_list:
            html +=  template.loader.get_template('blog/include/all_post.html').render(template.Context({'post':article}))

        mydict = {"html":html,"isend":isend}
        return HttpResponse(json.dumps(mydict),content_type="application/json")


class SearchView(BaseMixin,ListView):
    template_name = 'blog/search.html'
    context_object_name = 'article_list'
    paginate_by = PAGE_NUM

    def get_context_data(self,**kwargs):
        kwargs['s'] = self.request.GET.get('s','')
        return super(SearchView,self).get_context_data(**kwargs)

    def get_queryset(self):
        #获取搜索的关键字
        s = self.request.GET.get('s','')
        #在文章的标题,summary和tags中搜索关键字
        article_list = Article.objects.only('title','summary','tags')\
                .filter(Q(title__icontains=s)|Q(summary__icontains=s)|Q(tags__icontains=s)\
                ,status=0);
        return article_list


class TagView(BaseMixin,ListView):
    template_name = 'blog/tag.html'
    context_object_name = 'article_list'
    paginate_by = PAGE_NUM

    def get_queryset(self):
        tag = self.kwargs.get('tag','')
        article_list = Article.objects.only('tags').filter(tags__icontains=tag,status=0);

        return article_list


class CategoryView(BaseMixin,ListView):
    template_name = 'blog/category.html'
    context_object_name = 'article_list'
    paginate_by = PAGE_NUM

    def get_queryset(self):
        category = self.kwargs.get('category','')
        try:
            article_list = Category.objects.get(name=category).article_set.all()
        except Category.DoesNotExist:
            logger.error(u'[CategoryView]此分类不存在:[%s]' % category)
            raise Http404

        return article_list


class UserView(BaseMixin,TemplateView):
    template_name = 'blog/user.html'

    def get(self,request,*args,**kwargs):

        if not request.user.is_authenticated():
            logger.error(u'[UserView]用户未登陆')
            return render(request, 'blog/login.html')

        slug = self.kwargs.get('slug')

        if slug == 'changetx':
            self.template_name = 'blog/user_changetx.html'
            return super(UserView,self).get(request,*args,**kwargs)
        elif slug == 'changepassword':
            self.template_name = 'blog/user_changepassword.html'
            return super(UserView,self).get(request,*args,**kwargs)
        elif slug == 'changeinfo':
            self.template_name = 'blog/user_changeinfo.html'
            return super(UserView,self).get(request,*args,**kwargs)
        elif slug == 'message':
            self.template_name = 'blog/user_message.html'
            return super(UserView,self).get(request,*args,**kwargs)

        logger.error(u'[UserView]不存在此接口')
        raise Http404



class ColumnView(BaseMixin,ListView):
    queryset = Column.objects.all()
    template_name = 'blog/column.html'
    context_object_name = 'article_list'
    paginate_by = PAGE_NUM

    def get_context_data(self,**kwargs):
        column = self.kwargs.get('column','')
        try:
            kwargs['column'] = Column.objects.get(name=column)
        except Column.DoesNotExist:
            logger.error(u'[ColumnView]访问专栏不存在: [%s]' % column)
            raise Http404

        return super(ColumnView,self).get_context_data(**kwargs)

    def get_queryset(self):
        column = self.kwargs.get('column','')
        try:
            article_list = Column.objects.get(name=column).article.all()
        except Column.DoesNotExist:
            logger.error(u'[ColumnView]访问专栏不存在: [%s]' % column)
            raise Http404

        return article_list


class NewsView(BaseMixin,TemplateView):
    template_name = 'blog/news.html'
    
    def get_context_data(self, **kwargs):
        timeblocks = []

        #获取开始和终止的日期
        start_day = self.request.GET.get("start","0")
        end_day =  self.request.GET.get("end","6")
        start_day = int(start_day)
        end_day = int(end_day)

        start_date = datetime.datetime.now();

        #获取url中时间断的资讯
        for x in range(start_day,end_day+1):
            date = start_date - datetime.timedelta(x)
            news_list = News.objects.filter(pub_time__year=date.year,
                                        pub_time__month=date.month,
                                        pub_time__day = date.day)
                   
            if news_list:
                timeblocks.append(news_list)
        
        kwargs['timeblocks'] = timeblocks
        kwargs['active'] = start_day/7  #li中那个显示active

        return super(NewsView,self).get_context_data(**kwargs)


相关文章

网友评论

    本文标题:一个复杂的Django Model 和View 定义的案例

    本文链接:https://www.haomeiwen.com/subject/evrzdxtx.html