diff --git a/DjangoBlog/settings.py b/DjangoBlog/settings.py index 16797e7..b51a2d0 100644 --- a/DjangoBlog/settings.py +++ b/DjangoBlog/settings.py @@ -144,7 +144,7 @@ HAYSTACK_CONNECTIONS = { } # 自动更新搜索索引 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' -#允许使用用户名或密码登录 +# 允许使用用户名或密码登录 AUTHENTICATION_BACKENDS = ['accounts.user_login_backend.EmailOrUsernameModelBackend'] STATIC_ROOT = os.path.join(SITE_ROOT, 'collectedstatic') @@ -194,6 +194,10 @@ CACHES = { CACHE_MIDDLEWARE_SECONDS = 60 * 60 * 10 CACHE_MIDDLEWARE_KEY_PREFIX = "djangoblog" CACHE_MIDDLEWARE_ALIAS = 'default' + +SESSION_ENGINE = "django.contrib.sessions.backends.cache" +SESSION_CACHE_ALIAS = 'default' + OAHUTH = { 'sina': { 'appkey': '3161614143', @@ -207,7 +211,7 @@ OAHUTH = { } } -SITE_ID = 2 +SITE_ID = 1 BAIDU_NOTIFY_URL = "http://data.zz.baidu.com/urls?site=https://www.lylinux.net&token=1uAOGrMsUm5syDGn&type=original" # Emial: diff --git a/DjangoBlog/utils.py b/DjangoBlog/utils.py index 35f6e35..6d6e3f2 100644 --- a/DjangoBlog/utils.py +++ b/DjangoBlog/utils.py @@ -21,22 +21,39 @@ from pygments.formatters import html import logging logger = logging.getLogger('djangoblog') +from importlib import import_module +from django.conf import settings +SessionStore = import_module(settings.SESSION_ENGINE).SessionStore -def cache_decorator(expiration=3 * 60, cache_key=None): + +def get_max_articleid_commentid(): + from blog.models import Article + from comments.models import Comment + return (Article.objects.latest().pk, Comment.objects.latest().pk) + + +def cache_decorator(expiration=3 * 60): def wrapper(func): def news(*args, **kwargs): - key = cache_key + key = '' + try: + view = args[0] + key = view.get_cache_key() + except: + key = None + pass if not key: unique_str = repr((func, args, kwargs)) + m = md5(unique_str.encode('utf-8')) key = m.hexdigest() value = cache.get(key) if value: - logger.info('cache_decorator get cache %s' % func.__name__) + logger.info('cache_decorator get cache:%s key:%s' % (func.__name__, key)) return value else: - logger.info('cache_decorator set cache %s' % func.__name__) + logger.info('cache_decorator set cache:%s key:%s' % (func.__name__, key)) value = func(*args, **kwargs) cache.set(key, value, expiration) return value @@ -46,6 +63,23 @@ def cache_decorator(expiration=3 * 60, cache_key=None): return wrapper +def expire_view_cache(path, servername, serverport, key_prefix=None): + from django.http import HttpRequest + from django.utils.cache import get_cache_key + + request = HttpRequest() + request.META = {'SERVER_NAME': servername, 'SERVER_PORT': serverport} + request.path = path + + key = get_cache_key(request, key_prefix=key_prefix, cache=cache) + if key: + logger.info('expire_view_cache:get key:{path}'.format(path=path)) + if cache.get(key): + cache.delete(key) + return True + return False + + def block_code(text, lang, inlinestyles=False, linenos=False): if not lang: text = text.strip() diff --git a/accounts/urls.py b/accounts/urls.py index d753d24..dfd248d 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -22,5 +22,5 @@ from .forms import LoginForm urlpatterns = [ url(r'^login/$', views.LoginView.as_view(success_url='/'), name='login', kwargs={'authentication_form': LoginForm}), url(r'^register/$', views.RegisterView.as_view(success_url="/"), name='register'), - url(r'^logout/$', views.logout, name='logout') + url(r'^logout/$', views.LogoutView.as_view(), name='logout') ] diff --git a/accounts/views.py b/accounts/views.py index 55ad8e8..7312387 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -1,16 +1,21 @@ from django.shortcuts import render -from django.contrib.auth.views import login, logout from .forms import RegisterForm, LoginForm -from django.contrib.auth import authenticate -from django.views.generic.edit import FormView +from django.contrib.auth import authenticate, login, logout +# from django.views.generic.edit import FormView +from django.views.generic import FormView, RedirectView from django.contrib.auth import get_user_model from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from django.contrib.auth.forms import AuthenticationForm, UserCreationForm +from django.contrib.auth import REDIRECT_FIELD_NAME +from django.views.decorators.csrf import csrf_protect from django.contrib import auth from django.views.decorators.cache import never_cache from django.shortcuts import redirect +from django.utils.decorators import method_decorator +from django.views.decorators.debug import sensitive_post_parameters +from django.utils.http import is_safe_url # Create your views here. @@ -26,20 +31,39 @@ class RegisterView(FormView): return HttpResponseRedirect(url) -@never_cache -def LogOut(requests): - logout(request=requests, next_page='index') - return redirect('index') +class LogoutView(RedirectView): + url = '/login/' + + @method_decorator(never_cache) + def dispatch(self, request, *args, **kwargs): + return super(LogoutView, self).dispatch(request, *args, **kwargs) + + def get(self, request, *args, **kwargs): + from DjangoBlog.utils import cache + cache.clear() + logout(request) + return super(LogoutView, self).get(request, *args, **kwargs) class LoginView(FormView): form_class = LoginForm template_name = 'account/login.html' + success_url = '/' + redirect_field_name = REDIRECT_FIELD_NAME + + @method_decorator(sensitive_post_parameters('password')) + @method_decorator(csrf_protect) + @method_decorator(never_cache) + def dispatch(self, request, *args, **kwargs): + + return super(LoginView, self).dispatch(request, *args, **kwargs) def form_valid(self, form): form = AuthenticationForm(data=self.request.POST, request=self.request) if form.is_valid(): + from DjangoBlog.utils import cache + cache.clear() # login(self.request, form.get_user()) auth.login(self.request, form.get_user()) @@ -48,3 +72,9 @@ class LoginView(FormView): return self.render_to_response({ 'form': form }) + + def get_success_url(self): + redirect_to = self.request.GET.get(self.redirectfieldname) + if not is_safe_url(url=redirect_to, host=self.request.get_host()): + redirect_to = self.success_url + return redirect_to diff --git a/blog/admin.py b/blog/admin.py index 50782e2..5c646ed 100644 --- a/blog/admin.py +++ b/blog/admin.py @@ -17,9 +17,14 @@ class ArticleForm(forms.ModelForm): class ArticlelAdmin(admin.ModelAdmin): form = ArticleForm + def save_model(self, request, obj, form, change): + super(ArticlelAdmin, self).save_model(request, obj, form, change) + from DjangoBlog.utils import cache + cache.clear() + admin.site.register(Article, ArticlelAdmin) -#admin.site.register(BlogPage, ArticlelAdmin) +# admin.site.register(BlogPage, ArticlelAdmin) admin.site.register(Category) admin.site.register(Tag) admin.site.register(Links) diff --git a/blog/context_processors.py b/blog/context_processors.py index 872376e..74fabc6 100644 --- a/blog/context_processors.py +++ b/blog/context_processors.py @@ -14,9 +14,8 @@ """ from .models import Category, Article, Tag from django.conf import settings -from django.core.cache import cache - -from DjangoBlog.utils import logger +from comments.models import Comment +from DjangoBlog.utils import logger, cache def seo_processor(requests): @@ -36,7 +35,9 @@ def seo_processor(requests): 'SITE_BASE_URL': requests.scheme + '://' + requests.get_host() + '/', 'ARTICLE_SUB_LENGTH': settings.ARTICLE_SUB_LENGTH, 'nav_category_list': Category.objects.all(), - 'nav_pages': Article.objects.filter(type='p', status='p') + 'nav_pages': Article.objects.filter(type='p', status='p'), + 'MAX_COMMENTID': Comment.objects.latest().pk, + 'MAX_ARTICLEID': Article.objects.latest().pk } cache.set(key, value, 60 * 60 * 10) return value diff --git a/blog/models.py b/blog/models.py index dd9f900..f2f5ed2 100644 --- a/blog/models.py +++ b/blog/models.py @@ -68,6 +68,7 @@ class Article(BaseModel): ordering = ['-pub_time'] verbose_name = "文章" verbose_name_plural = verbose_name + get_latest_by = 'created_time' def get_absolute_url(self): @@ -110,10 +111,11 @@ class Article(BaseModel): self.views += 1 self.save(update_fields=['views']) - @cache_decorator(60 * 60 * 10) + """ def comment_list(self): comments = self.comment_set.all() parent_comments = comments.filter(parent_comment=None) + """ def get_admin_url(self): info = (self._meta.app_label, self._meta.model_name) diff --git a/blog/urls.py b/blog/urls.py index 5588df9..1bb0c31 100644 --- a/blog/urls.py +++ b/blog/urls.py @@ -20,12 +20,21 @@ from haystack.forms import ModelSearchForm from haystack.query import SearchQuerySet from haystack.views import SearchView + +def key_prefixer(request): + # if it's not there, don't cache + # return request.GET.get('number') + return "123" + + urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index'), url(r'^page/(?P\d+)$', views.IndexView.as_view(), name='index_page'), url(r'^article/(?P\d+)/(?P\d+)/(?P\d+)/(?P\d+)-(?P\S+).html$', - cache_page(60 * 60 * 10)(views.ArticleDetailView.as_view()), + # cache_page(60 * 60 * 10, key_prefix="blogdetail")(views.ArticleDetailView.as_view()), + views.ArticleDetailView.as_view(), name='detail'), + url(r'^blogpage/(?P\d+)/(?P\d+)/(?P\d+)/(?P\d+)-(?P\S+).html$', views.ArticleDetailView.as_view(), name='pagedetail'), diff --git a/blog/views.py b/blog/views.py index 5df1f8f..8af6f5b 100644 --- a/blog/views.py +++ b/blog/views.py @@ -2,6 +2,8 @@ from django.shortcuts import render # Create your views here. from django.views.generic.list import ListView +from django.views.generic import TemplateView +from django.views.decorators.cache import cache_page from django.views.generic.detail import DetailView from django.views.generic import UpdateView from django.views.generic.edit import CreateView, FormView @@ -22,6 +24,9 @@ from django.views.decorators.csrf import csrf_exempt import os from django.contrib.auth.decorators import login_required from DjangoBlog.utils import cache, cache_decorator +from django.utils.cache import get_cache_key +from django.utils.decorators import classonlymethod +from django.utils.decorators import method_decorator """ class SeoProcessor(): @@ -41,7 +46,16 @@ class SeoProcessor(): """ -class ArticleListView(ListView): +class CachedTemplateView(ListView): + @classonlymethod + def as_view(cls, **initkwargs): + # print(request) + + view = super(CachedTemplateView, cls).as_view(**initkwargs) + return cache_page(60 * 60 * 10)(view) + + +class ArticleListView(CachedTemplateView): # template_name属性用于指定使用哪个模板进行渲染 template_name = 'blog/article_index.html' @@ -53,15 +67,25 @@ class ArticleListView(ListView): paginate_by = settings.PAGINATE_BY page_kwarg = 'page' + def get_cache_key(self): + raise NotImplementedError("implement this function") + class IndexView(ArticleListView): def get_queryset(self): + """ + try: + # _auth_user_id + from DjangoBlog.utils import SessionStore + s = SessionStore(session_key='_auth_user_id') + print(s) + except: + pass + """ article_list = Article.objects.filter(type='a', status='p') - # for article in article_list: # article.body = article.body[0:settings.ARTICLE_SUB_LENGTH] # # article.body = markdown2.markdown(article.body) - return article_list @@ -80,7 +104,7 @@ class ArticleDetailView(DetailView): def get_context_data(self, **kwargs): articleid = int(self.kwargs[self.pk_url_kwarg]) - print(str(articleid) + "get_context_data") + comment_form = CommentForm() u = self.request.user @@ -92,7 +116,6 @@ class ArticleDetailView(DetailView): user = self.request.user comment_form.fields["email"].initial = user.email comment_form.fields["name"].initial = user.username - key = "article_comment_{}".format(articleid) article_comments = self.object.comment_set.all() @@ -105,7 +128,14 @@ class ArticleDetailView(DetailView): return super(ArticleDetailView, self).get_context_data(**kwargs) - """ + @classonlymethod + def as_view(cls, **initkwargs): + self = cls(**initkwargs) + keyperfix = "blogdetail" + return cache_page(60 * 60 * 10, key_prefix=keyperfix)(super(ArticleDetailView, cls).as_view(**initkwargs)) + + +""" def post(self, request, *args, **kwargs): form = CommentForm(request.POST) @@ -114,7 +144,6 @@ class ArticleDetailView(DetailView): pass """ - ''' class PageDetailView(ArticleDetailView): model = BlogPage @@ -135,6 +164,11 @@ class CategoryDetailView(ArticleListView): # pk_url_kwarg = 'article_name' page_type = "分类目录归档" + """ + def get_cache_key(self): + categoryname = self.kwargs['category_name'] + return "category_list:{categoryname}".format(categoryname=categoryname) + """ def get_queryset(self): categoryname = self.kwargs['category_name'] @@ -162,7 +196,6 @@ class AuthorDetailView(ArticleListView): def get_queryset(self): author_name = self.kwargs['author_name'] - article_list = Article.objects.filter(author__username=author_name) return article_list @@ -189,7 +222,6 @@ class TagDetailView(ArticleListView): def get_queryset(self): tag_name = self.kwargs['tag_name'] - article_list = Article.objects.filter(tags__name=tag_name) return article_list diff --git a/comments/models.py b/comments/models.py index c1a9c9d..61650f3 100644 --- a/comments/models.py +++ b/comments/models.py @@ -25,6 +25,7 @@ class Comment(models.Model): ordering = ['created_time'] verbose_name = "评论" verbose_name_plural = verbose_name + get_latest_by = 'created_time' def send_comment_email(self, msg): try: diff --git a/comments/views.py b/comments/views.py index c474d91..ce33037 100644 --- a/comments/views.py +++ b/comments/views.py @@ -6,12 +6,20 @@ from blog.models import Article from .forms import CommentForm from django.views.generic.edit import FormView from django.http import HttpResponseRedirect -from django.core.urlresolvers import reverse from django.contrib.auth import get_user_model from django import forms + +""" +from django.core.urlresolvers import reverse from django.contrib import auth +from django.utils.decorators import method_decorator +from django.views.decorators.cache import never_cache +from django.views.decorators.csrf import csrf_protect +from django.contrib.auth.decorators import login_required +""" +# @method_decorator(login_required,name='dispatch') class CommentPostView(FormView): form_class = CommentForm template_name = 'blog/article_detail.html' @@ -64,5 +72,12 @@ class CommentPostView(FormView): comment.parent_comment = parent_comment comment.save(True) - # return HttpResponseRedirect(article.get_absolute_url() + "#div-comment-" + comment.pk) + from DjangoBlog.utils import expire_view_cache, cache + from django.contrib.sites.models import Site + path = article.get_absolute_url() + site = Site.objects.get_current().domain + + expire_view_cache(path, servername=site, serverport=self.request.get_port(), key_prefix='blogdetail') + if cache.get('seo_processor'): + cache.delete('seo_processor') return HttpResponseRedirect("%s#div-comment-%d" % (article.get_absolute_url(), comment.pk)) diff --git a/templates/share_layout/base.html b/templates/share_layout/base.html index 87f4a2c..5480514 100644 --- a/templates/share_layout/base.html +++ b/templates/share_layout/base.html @@ -65,7 +65,7 @@ {% block content %} {% endblock %} - {% cache 36000 sidebar request.user.username %} + {% cache 36000 sidebar request.user.username MAX_COMMENTID MAX_ARTICLEID %} {% block sidebar %} {% endblock %} {% endcache %}