diff --git a/.travis.yml b/.travis.yml
index 3f06c6e..c6c191d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,11 +9,6 @@ services:
env:
global:
- DJANGO_SETTINGS_MODULE="travis_test.travis_settings"
- matrix:
- - DJANGO="Django==1.8"
- - DJANGO="Django==1.9"
- - DJANGO="Django==1.10"
- - DJANGO="Django==1.11"
branches:
only:
- master
diff --git a/DjangoBlog/settings.py b/DjangoBlog/settings.py
index 1b55ec1..26cc311 100644
--- a/DjangoBlog/settings.py
+++ b/DjangoBlog/settings.py
@@ -49,7 +49,7 @@ INSTALLED_APPS = [
'compressor'
]
-MIDDLEWARE_CLASSES = [
+MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.gzip.GZipMiddleware',
diff --git a/DjangoBlog/sitemap.py b/DjangoBlog/sitemap.py
index 18e11ed..72fcd04 100644
--- a/DjangoBlog/sitemap.py
+++ b/DjangoBlog/sitemap.py
@@ -17,7 +17,7 @@ from django.contrib.sitemaps import Sitemap
from blog.models import Article, Category, Tag
from accounts.models import BlogUser
from django.contrib.sitemaps import GenericSitemap
-from django.core.urlresolvers import reverse
+from django.urls import reverse
class StaticViewSitemap(Sitemap):
diff --git a/DjangoBlog/tests.py b/DjangoBlog/tests.py
index d95b8bf..fcde227 100644
--- a/DjangoBlog/tests.py
+++ b/DjangoBlog/tests.py
@@ -17,7 +17,7 @@ from django.test import Client, RequestFactory, TestCase
from blog.models import Article, Category, Tag
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
-from django.core.urlresolvers import reverse
+from django.urls import reverse
import datetime
from DjangoBlog.utils import *
diff --git a/DjangoBlog/urls.py b/DjangoBlog/urls.py
index 8ed7d7f..eaca1b6 100644
--- a/DjangoBlog/urls.py
+++ b/DjangoBlog/urls.py
@@ -36,14 +36,14 @@ handler500 = 'blog.views.server_error_view'
urlpatterns = [
url(r'^admin/', admin.site.urls),
- url(r'', include('blog.urls', namespace='blog', app_name='blog')),
+ url(r'', include('blog.urls', namespace='blog')),
- url(r'', include('comments.urls', namespace='comment', app_name='comments')),
- url(r'', include('accounts.urls', namespace='account', app_name='accounts')),
- url(r'', include('oauth.urls', namespace='oauth', app_name='oauth')),
+ url(r'', include('comments.urls', namespace='comment')),
+ url(r'', include('accounts.urls', namespace='account')),
+ url(r'', include('oauth.urls', namespace='oauth')),
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
url(r'^feed/$', DjangoBlogFeed()),
url(r'^search', include('haystack.urls'), name='search'),
- url(r'', include('servermanager.urls', namespace='servermanager', app_name='servermanagers'))
+ url(r'', include('servermanager.urls', namespace='servermanager'))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
diff --git a/README.md b/README.md
index 6f13d82..9912930 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# DjangoBlog
-基于`python3.5`和`Django1.10`的博客。
+基于`python3.5`和`Django2.0`的博客。
-[](https://travis-ci.org/liangliangyy/DjangoBlog) [](https://coveralls.io/github/liangliangyy/DjangoBlog?branch=master) [](https://requires.io/github/liangliangyy/DjangoBlog/requirements/?branch=master) []() []() []() []()
+[](https://travis-ci.org/liangliangyy/DjangoBlog) [](https://coveralls.io/github/liangliangyy/DjangoBlog?branch=master) [](https://requires.io/github/liangliangyy/DjangoBlog/requirements/?branch=master) []() []() []() []()
## 主要功能:
- 文章,页面,分类目录,标签的添加,删除,编辑等。文章及页面支持`Markdown`,支持代码高亮。
@@ -14,7 +14,6 @@
- 简单的SEO功能,新建文章等会自动通知Google和百度。
- 集成了简单的图床功能。
- 集成`django-compressor`,自动压缩`css`,`js`。
-- 基于`python3`,支持`Django`多版本。`Django`的1.8,1.9,1.10,1.11均测试通过。
- 网站异常邮件提醒,若有未捕捉到的异常会自动发送提醒邮件。
- 集成了微信公众号功能,现在可以使用微信公众号来管理你的vps了。
## 安装
diff --git a/accounts/models.py b/accounts/models.py
index d396bd3..5bf882f 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -1,6 +1,6 @@
from django.db import models
from django.contrib.auth.models import AbstractUser, BaseUserManager
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.contrib.sites.models import Site
from django.utils.timezone import now
@@ -9,6 +9,7 @@ from django.utils.timezone import now
class BlogUser(AbstractUser):
nickname = models.CharField('昵称', max_length=50, blank=True)
+ nickname = models.CharField('昵称', max_length=100, blank=True)
mugshot = models.ImageField('头像', upload_to='upload/mugshots', blank=True)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
diff --git a/accounts/tests.py b/accounts/tests.py
index 2784463..db743e6 100644
--- a/accounts/tests.py
+++ b/accounts/tests.py
@@ -4,7 +4,7 @@ from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
import datetime
from accounts.models import BlogUser
-from django.core.urlresolvers import reverse
+from django.urls import reverse
# Create your tests here.
diff --git a/accounts/urls.py b/accounts/urls.py
index dfd248d..a648a76 100644
--- a/accounts/urls.py
+++ b/accounts/urls.py
@@ -19,6 +19,8 @@ from django.contrib.auth import views as auth_view
from . import views
from .forms import LoginForm
+app_name="accounts"
+
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'),
diff --git a/accounts/views.py b/accounts/views.py
index e092ae6..1e8548a 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -6,7 +6,7 @@ from django.contrib.auth import authenticate, login, logout
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.urls 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
diff --git a/blog/middleware.py b/blog/middleware.py
index 69e4243..00e0445 100644
--- a/blog/middleware.py
+++ b/blog/middleware.py
@@ -19,33 +19,17 @@ from DjangoBlog.utils import cache
class OnlineMiddleware(object):
- def process_request(self, request):
- self.start_time = time.time()
+ def __init__(self, get_response=None):
+ self.get_response = get_response
+ super().__init__()
- def process_view(self, request, view_func, view_args, view_kwargs):
- """
- 处理当前在线人数
- """
+ def __call__(self, request):
+ start_time = time.time()
+ response = self.get_response(request)
http_user_agent = request.META.get('HTTP_USER_AGENT', [])
if 'Spider' in http_user_agent or 'spider' in http_user_agent:
- return
+ return response
- online_ips = cache.get("online_ips", [])
- if online_ips:
- online_ips = cache.get_many(online_ips).keys()
- online_ips = list(online_ips)
- ip = get_real_ip(request)
-
- cache.set(ip, 0, 5 * 60)
-
- if ip not in online_ips:
- online_ips.append(ip)
- s = type(online_ips)
- cache.set("online_ips", online_ips)
-
- def process_response(self, request, response):
- cast_time = 0.921
- if self.__dict__ and 'start_time' in self.__dict__:
- cast_time = time.time() - self.start_time
+ cast_time = time.time() - start_time
response.content = response.content.replace(b'', str.encode(str(cast_time)[:5]))
return response
diff --git a/blog/models.py b/blog/models.py
index ead1e76..6999645 100644
--- a/blog/models.py
+++ b/blog/models.py
@@ -1,5 +1,5 @@
from django.db import models
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django.conf import settings
from uuslug import slugify
@@ -125,7 +125,7 @@ class Article(BaseModel):
class Category(BaseModel):
"""文章分类"""
name = models.CharField('分类名', max_length=30, unique=True)
- parent_category = models.ForeignKey('self', verbose_name="父级分类", blank=True, null=True)
+ parent_category = models.ForeignKey('self', verbose_name="父级分类", blank=True, null=True, on_delete=models.CASCADE)
class Meta:
ordering = ['name']
diff --git a/blog/templatetags/blog_tags.py b/blog/templatetags/blog_tags.py
index 1e71c23..5605b1b 100644
--- a/blog/templatetags/blog_tags.py
+++ b/blog/templatetags/blog_tags.py
@@ -18,7 +18,7 @@ from django.conf import settings
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
import random
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from blog.models import Article, Category, Tag, Links, SideBar
from django.utils.encoding import force_text
from django.shortcuts import get_object_or_404
@@ -266,7 +266,7 @@ def gravatar(email, size=40):
return mark_safe('
' % (url, size, size))
-@register.assignment_tag
+@register.simple_tag
def query(qs, **kwargs):
""" template tag which allows queryset filtering. Usage:
{% query books author=author as mybooks %}
@@ -275,3 +275,5 @@ def query(qs, **kwargs):
{% endfor %}
"""
return qs.filter(**kwargs)
+
+
diff --git a/blog/urls.py b/blog/urls.py
index 870e293..b68ce77 100644
--- a/blog/urls.py
+++ b/blog/urls.py
@@ -13,38 +13,32 @@
@time: 2016/11/2 下午7:15
"""
-from django.conf.urls import url
+from django.urls import path
from django.views.decorators.cache import cache_page
from . import views
from haystack.forms import ModelSearchForm
from haystack.query import SearchQuerySet
from haystack.views import SearchView
+app_name = "blog"
urlpatterns = [
- url(r'^$', views.IndexView.as_view(), name='index'),
- url(r'^page/(?P\d+)$', views.IndexView.as_view(), name='index_page'),
+ path(r'', views.IndexView.as_view(), name='index'),
+ path(r'page//', views.IndexView.as_view(), name='index_page'),
- url(r'^article/(?P\d+)/(?P\d+)/(?P\d+)/(?P\d+).html$',
- views.ArticleDetailView.as_view(),
- name='detailbyid'),
+ path(r'article////.html',
+ views.ArticleDetailView.as_view(),
+ name='detailbyid'),
- url(r'^blogpage/(?P\d+)/(?P\d+)/(?P\d+)/(?P\d+)-(?P[\w-]+).html$',
- views.ArticleDetailView.as_view(),
- name='pagedetail'),
+ path(r'category/.html', views.CategoryDetailView.as_view(), name='category_detail'),
+ path(r'category//.html', views.CategoryDetailView.as_view(),
+ name='category_detail_page'),
- url(r'^category/(?P[\w-]+).html$', views.CategoryDetailView.as_view(), name='category_detail'),
- url(r'^category/(?P[\w-]+)/(?P\d+).html$', views.CategoryDetailView.as_view(),
- name='category_detail_page'),
- # url(r'^category/(?P[\w-]+)/(?P\d+).html$', views.CategoryDetailView.as_view(),
- # name='category_detail'),
+ path(r'author/.html', views.AuthorDetailView.as_view(), name='author_detail'),
+ path(r'author//).html', views.AuthorDetailView.as_view(),
+ name='author_detail_page'),
- url(r'^author/(?P\w+).html$', views.AuthorDetailView.as_view(), name='author_detail'),
- url(r'^author/(?P\w+)/(?P\d+).html$', views.AuthorDetailView.as_view(),
- name='author_detail_page'),
-
- url(r'^tag/(?P[\w-]+).html$', views.TagDetailView.as_view(), name='tag_detail'),
- url(r'^tag/(?P[\w-]+)/(?P\d+).html$', views.TagDetailView.as_view(), name='tag_detail_page'),
-
- url(r'^upload', views.fileupload, name='upload'),
- url(r'^refresh', views.refresh_memcache, name='refresh')
+ path(r'tag/.html', views.TagDetailView.as_view(), name='tag_detail'),
+ path(r'tag//).html', views.TagDetailView.as_view(), name='tag_detail_page'),
+ path(r'upload', views.fileupload, name='upload'),
+ path(r'refresh', views.refresh_memcache, name='refresh')
]
diff --git a/blog/views.py b/blog/views.py
index 8009067..51b3076 100644
--- a/blog/views.py
+++ b/blog/views.py
@@ -218,11 +218,11 @@ def fileupload(request):
isimage = len([i for i in imgextensions if fname.find(i) >= 0]) > 0
basepath = r'/var/www/resource/{type}/{timestr}'.format(
- type='files' if not isimage else'image', timestr=timestr)
+ type='files' if not isimage else 'image', timestr=timestr)
if settings.TESTING:
basepath = settings.BASE_DIR + '/uploads'
url = 'https://resource.lylinux.net/{type}/{timestr}/{filename}'.format(
- type='files' if not isimage else'image', timestr=timestr, filename=filename)
+ type='files' if not isimage else 'image', timestr=timestr, filename=filename)
if not os.path.exists(basepath):
os.makedirs(basepath)
savepath = os.path.join(basepath, filename)
@@ -256,17 +256,23 @@ def refresh_memcache(request):
return HttpResponse(e)
-def page_not_found_view(request):
+def page_not_found_view(request, exception):
+ if exception:
+ logger.error(exception)
url = request.get_full_path()
return render(request, 'blog/error_page.html',
{'message': '哎呀,您访问的地址 ' + url + ' 是一个未知的地方。请点击首页看看别的?', 'statuscode': '404'})
-def server_error_view(request):
+def server_error_view(request, exception):
+ if exception:
+ logger.error(exception)
return render(request, 'blog/error_page.html',
{'message': '哎呀,出错了,我已经收集到了错误信息,之后会抓紧抢修,请点击首页看看别的?', 'statuscode': '500'})
-def permission_denied_view(request):
+def permission_denied_view(request, exception):
+ if exception:
+ logger.error(exception)
return render(request, 'blog/error_page.html',
{'message': '哎呀,您没有权限访问此页面,请点击首页看看别的?', 'statuscode': '403'})
diff --git a/comments/models.py b/comments/models.py
index 0f55201..9934ba4 100644
--- a/comments/models.py
+++ b/comments/models.py
@@ -13,7 +13,7 @@ class Comment(models.Model):
last_mod_time = models.DateTimeField('修改时间', default=now)
author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='作者', on_delete=models.CASCADE)
article = models.ForeignKey(Article, verbose_name='文章', on_delete=models.CASCADE)
- parent_comment = models.ForeignKey('self', verbose_name="上级评论", blank=True, null=True)
+ parent_comment = models.ForeignKey('self', verbose_name="上级评论", blank=True, null=True, on_delete=models.CASCADE)
is_enable = models.BooleanField('是否显示', default=True, blank=False, null=False)
class Meta:
diff --git a/comments/templatetags/comments_tags.py b/comments/templatetags/comments_tags.py
index b831e7d..a78e8b6 100644
--- a/comments/templatetags/comments_tags.py
+++ b/comments/templatetags/comments_tags.py
@@ -22,7 +22,7 @@ from comments.forms import CommentForm
register = template.Library()
-@register.assignment_tag
+@register.simple_tag
def parse_commenttree(commentlist, comment):
"""获得当前评论子评论的列表
用法: {% parse_commenttree article_comments comment as childcomments %}
diff --git a/comments/tests.py b/comments/tests.py
index fe54671..9a758a5 100644
--- a/comments/tests.py
+++ b/comments/tests.py
@@ -2,7 +2,7 @@ from django.test import Client, RequestFactory, TestCase
from blog.models import Article, Category, Tag
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
-from django.core.urlresolvers import reverse
+from django.urls import reverse
import datetime
from accounts.models import BlogUser
from comments.templatetags.comments_tags import *
diff --git a/comments/urls.py b/comments/urls.py
index f5af5fd..0bcb847 100644
--- a/comments/urls.py
+++ b/comments/urls.py
@@ -13,10 +13,11 @@
@time: 2016/11/12 下午3:03
"""
-from django.conf.urls import url
+from django.urls import path
from . import views
+app_name = "comments"
urlpatterns = [
- # url(r'^postcomment/(?P\d+)$', views.CommentPostView.as_view(), name='postcomment'),
- url(r'^article/(?P\d+)/postcomment$', views.CommentPostView.as_view(), name='postcomment'),
+ # url(r'^po456stcomment/(?P\d+)$', views.CommentPostView.as_view(), name='postcomment'),
+ path('article//postcomment', views.CommentPostView.as_view(), name='postcomment'),
]
diff --git a/comments/views.py b/comments/views.py
index 34c9338..a25ecad 100644
--- a/comments/views.py
+++ b/comments/views.py
@@ -46,7 +46,7 @@ class CommentPostView(FormView):
article_id = self.kwargs['article_id']
article = Article.objects.get(pk=article_id)
- if not self.request.user.is_authenticated():
+ if not self.request.user.is_authenticated:
email = form.cleaned_data['email']
username = form.cleaned_data['name']
@@ -64,12 +64,8 @@ class CommentPostView(FormView):
comment.save(True)
from DjangoBlog.blog_signals import comment_save_signal
- port = 80
- try:
- # django1.8 没有这个方法...
- port = self.request.get_port()
- except:
- pass
+
+ port = self.request.get_port()
username = self.request.user.username if self.request.user else ''
comment_save_signal.send(sender=self.__class__, comment_id=comment.id, username=username, serverport=port)
return HttpResponseRedirect("%s#div-comment-%d" % (article.get_absolute_url(), comment.pk))
diff --git a/oauth/models.py b/oauth/models.py
index 76900c8..4a00c97 100644
--- a/oauth/models.py
+++ b/oauth/models.py
@@ -6,7 +6,8 @@ from django.utils.timezone import now
class OAuthUser(models.Model):
- author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='用户', blank=True, null=True)
+ author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='用户', blank=True, null=True,
+ on_delete=models.CASCADE)
openid = models.CharField(max_length=50)
nikename = models.CharField(max_length=50, verbose_name='昵称')
token = models.CharField(max_length=150, null=True, blank=True)
diff --git a/oauth/templatetags/oauth_tags.py b/oauth/templatetags/oauth_tags.py
index 96b74cd..c336b03 100644
--- a/oauth/templatetags/oauth_tags.py
+++ b/oauth/templatetags/oauth_tags.py
@@ -13,7 +13,7 @@
@time: 2017/3/4 下午3:22
"""
from oauth.oauthmanager import get_oauth_apps
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from django import template
from django.conf import settings
diff --git a/oauth/urls.py b/oauth/urls.py
index c0bc44a..53c4013 100644
--- a/oauth/urls.py
+++ b/oauth/urls.py
@@ -13,14 +13,15 @@
@time: 2016/11/26 下午5:25
"""
-from django.conf.urls import url
+from django.urls import path
from django.views.decorators.cache import cache_page
from . import views
+app_name = "oauth"
urlpatterns = [
- url(r'^oauth/authorize$', views.authorize),
- url(r'^oauth/requireemail/(?P\d+).html', views.RequireEmailView.as_view(), name='require_email'),
- url(r'^oauth/emailconfirm/(?P\d+)/(?P\S+).html', views.emailconfirm, name='email_confirm'),
- url(r'^oauth/bindsuccess/(?P\d+).html', views.bindsuccess, name='bindsuccess'),
- url(r'^oauth/oauthlogin$', views.oauthlogin,name='oauthlogin')
+ path(r'oauth/authorize', views.authorize),
+ path(r'oauth/requireemail/.html', views.RequireEmailView.as_view(), name='require_email'),
+ path(r'oauth/emailconfirm/)/.html', views.emailconfirm, name='email_confirm'),
+ path(r'oauth/bindsuccess/.html', views.bindsuccess, name='bindsuccess'),
+ path(r'oauth/oauthlogin', views.oauthlogin, name='oauthlogin')
]
diff --git a/oauth/views.py b/oauth/views.py
index 6975f13..a199718 100644
--- a/oauth/views.py
+++ b/oauth/views.py
@@ -10,7 +10,7 @@ from django.contrib.auth import login
from django.shortcuts import get_object_or_404
from django.views.generic import FormView, RedirectView
from oauth.forms import RequireEmailForm
-from django.core.urlresolvers import reverse
+from django.urls import reverse
from DjangoBlog.utils import send_email, get_md5
from django.contrib.sites.models import Site
from django.core.exceptions import ObjectDoesNotExist
diff --git a/requirements.txt b/requirements.txt
index 90da994..ecfbd56 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,23 +1,27 @@
appdirs==1.4.3
-coverage==4.4.1
-Django==1.11.7
+bottle==0.12.13
+certifi==2017.11.5
+chardet==3.0.4
+coverage==4.4.2
+Django==2.0.1
django-appconf==1.0.2
django-autoslug==1.9.3
django-compressor==2.2
django-debug-toolbar==1.9.1
django-haystack==2.6.1
django-ipware==1.1.6
-django-pagedown==0.1.3
+django-pagedown==1.0.4
django-uuslug==1.1.8
+idna==2.6
jieba==0.39
jsonpickle==0.9.5
markdown2==2.3.5
-mistune==0.8.1
+mistune==0.8.3
olefile==0.44
packaging==16.8
-Pillow==4.3.0
+Pillow==5.0.0
Pygments==2.2.0
-PyMySQL==0.7.11
+PyMySQL==0.8.0
pyparsing==2.2.0
python-memcached==1.58
python-slugify==1.2.4
@@ -27,8 +31,9 @@ requests==2.18.4
rjsmin==1.0.12
six==1.11.0
sqlparse==0.2.4
-Unidecode==0.4.21
+Unidecode==1.0.22
urllib3==1.22
webencodings==0.5.1
-WeRoBot==1.1.1
+WeRoBot==1.2.0
Whoosh==2.7.4
+xmltodict==0.11.0
diff --git a/servermanager/urls.py b/servermanager/urls.py
index 5ee7703..d9775ab 100644
--- a/servermanager/urls.py
+++ b/servermanager/urls.py
@@ -13,11 +13,12 @@
@time: 2017/8/27 上午2:27
"""
-from django.conf.urls import url
+from django.urls import path
from werobot.contrib.django import make_view
from .robot import robot
+app_name = "servermanager"
urlpatterns = [
- url(r'^robot/', make_view(robot)),
+ path(r'robot', make_view(robot)),
]