Merge branch 'master' of github.com:liangliangyy/DjangoBlog into dev

sh_branch
liangliangyy 7 years ago
commit b67cc4ffb7

1
.gitignore vendored

@ -76,3 +76,4 @@ werobot_session
django.jpg
uploads/
settings_production.py
werobot_session.db

@ -2,6 +2,12 @@ language: python
python:
- "3.5"
- "3.6"
matrix:
include:
- python: "3.7"
dist: xenial
allow_failures:
- python: "3.7"
services:
- mysql
env:
@ -29,4 +35,4 @@ script:
- coverage run manage.py test
after_success:
- coveralls
- codecov
- codecov

@ -31,7 +31,10 @@ class ElasticSearchBackend(BaseSearchBackend):
def __init__(self, connection_alias, **connection_options):
super(ElasticSearchBackend, self).__init__(connection_alias, **connection_options)
self.manager = ArticleDocumentManager()
self._rebuild(None)
try:
self._rebuild(None)
except:
pass
def _get_models(self, iterable):
models = iterable if iterable else Article.objects.all()
@ -54,6 +57,7 @@ class ElasticSearchBackend(BaseSearchBackend):
self.manager.update_docs(docs)
def update(self, index, iterable, commit=True):
models = self._get_models(iterable)
self.manager.update_docs(models)

@ -46,6 +46,7 @@ urlpatterns = [
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
url(r'^feed/$', DjangoBlogFeed()),
url(r'^rss/$', DjangoBlogFeed()),
url(r'^search', include('haystack.urls'), name='search'),
url(r'', include('servermanager.urls', namespace='servermanager')),
url(r'', include('owntracks.urls', namespace='owntracks'))

@ -624,7 +624,7 @@ class WhooshSearchBackend(BaseSearchBackend):
if string_key in index.fields and hasattr(index.fields[string_key], 'convert'):
# Special-cased due to the nature of KEYWORD fields.
if index.fields[string_key].is_multivalued:
if value is None or len(value) is 0:
if value is None or len(value) == 0:
additional_fields[string_key] = []
else:
additional_fields[string_key] = value.split(',')

@ -109,7 +109,7 @@ Execute: `./manage.py runserver`
Open up a browser and visit: http://127.0.0.1:8000/ , the you will see the blog.
## More configurations
[More configurations details](/bin/config.md)
[More configurations details](/docs/config-en.md)
## About the issues

@ -111,7 +111,7 @@ CREATE DATABASE `djangoblog` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8
浏览器打开: http://127.0.0.1:8000/ 就可以看到效果了。
## 更多配置:
[更多配置介绍](/bin/config.md)
[更多配置介绍](/docs/config.md)
## 问题相关

@ -5,6 +5,8 @@ from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.forms import ReadOnlyPasswordHashField
# Register your models here.
from .models import BlogUser
from django.utils.translation import gettext, gettext_lazy as _
from django.contrib.auth.forms import UsernameField
class BlogUserCreationForm(forms.ModelForm):
@ -28,23 +30,29 @@ class BlogUserCreationForm(forms.ModelForm):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.source = 'adminsite'
user.save()
return user
class BlogUserChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField
class BlogUserChangeForm(UserChangeForm):
password = ReadOnlyPasswordHashField(
label=_("Password"),
help_text=_(
"Raw passwords are not stored, so there is no way to see this "
"user's password, but you can change the password using "
"<a href=\"{}\">this form</a>."
),
)
email = forms.EmailField(label="Email", widget=forms.EmailInput)
class Meta:
model = BlogUser
fields = ('email', 'password', 'is_active')
fields = '__all__'
field_classes = {'username': UsernameField}
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class BlogUserAdmin(UserAdmin):

@ -11,6 +11,7 @@ class BlogUser(AbstractUser):
nickname = models.CharField('昵称', max_length=100, blank=True)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
source = models.CharField("创建涞源", max_length=100, blank=True)
# objects = BlogUserManager()

@ -33,6 +33,7 @@ class RegisterView(FormView):
if form.is_valid():
user = form.save(False)
user.is_active = False
user.source = 'Register'
user.save(True)
site = get_current_site().domain
sign = get_md5(get_md5(settings.SECRET_KEY + str(user.id)))
@ -106,7 +107,7 @@ class LoginView(FormView):
if cache and cache is not None:
cache.clear()
logger.info(self.redirect_field_name)
redirect_to = self.request.GET.get(self.redirect_field_name)
auth.login(self.request, form.get_user())
return super(LoginView, self).form_valid(form)
# return HttpResponseRedirect('/')

@ -0,0 +1,64 @@
# Introduction to main features settings
## Cache:
Cache using `memcache` for default. If you don't have `memcache` environment, you can remove the `default` setting in `CACHES` and change `locmemcache` to `default`.
```python
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
'KEY_PREFIX': 'django_test' if TESTING else 'djangoblog',
'TIMEOUT': 60 * 60 * 10
},
'locmemcache': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 10800,
'LOCATION': 'unique-snowflake',
}
}
```
## OAuth Login:
QQ, Weibo, Google, GitHub and Facebook are now supported for OAuth login. Fetch OAuth login permissions from the corresponding open platform, and save them with `appkey`, `appsecret` and callback address in **Backend->OAuth** configuration.
### Callback address examples:
QQ: http://your-domain-name/oauth/authorize?type=qq
Weibo: http://your-domain-name/oauth/authorize?type=weibo
type is in the type field of `oauthmanager`.
## owntracks:
owntracks is a location tracking application. It will send your locaiton to the server by timing.Simple support owntracks features. Just install owntracks app and set api address as `your-domain-name/owntracks/logtracks`. Visit `your-domain-name/owntracks/show_dates` and you will see the date with latitude and langitude, click it and see the motion track. The map is drawn by AMap.
## Email feature:
Same as before, Configure your own error msg recvie email information with`ADMINS = [('liangliang', 'liangliangyy@gmail.com')]` in `settings.py`. And modify:
```python
EMAIL_HOST = 'smtp.zoho.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = os.environ.get('DJANGO_EMAIL_USER')
EMAIL_HOST_PASSWORD = os.environ.get('DJANGO_EMAIL_PASSWORD')
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = os.environ.get('DJANGO_EMAIL_USER')
```
with your email account information.
## WeChat Official Account
Simple wechat official account features integrated. Set token as `your-domain-name/robot` in wechat backend. Default token is `lylinux`, you can change it to your own in `servermanager/robot.py`. Add a new command in `Backend->Servermanager->command`, in this way, you can manage the system through wechat official account.
## Introduction to website configuration
You can add website configuration in **Backend->BLOG->WebSiteConfiguration**. Such as: keywords, description, Google Ad, website stats code, case number, etc.
OAuth user avatar path is saved in *StaticFileSavedAddress*. Please input absolute path, code directory for default.
## Source code highlighting
If the code block in your article didn't show hightlight, please write the code blocks as following:
![](https://resource.lylinux.net/image/codelang.png)
That is, you should add the corresponding language name before the code block.
## Update
If you get errors as following while executing database migrations:
```python
django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1"))
```
This problem may cause by the mysql version under 5.6, a new version( >= 5.6 ) mysql is needed.

@ -19,7 +19,7 @@ CACHES = {
```
## oauth登录:
现在已经支持微博GoogleGitHubFacebook登录需要在其对应的开放平台申请oauth登录权限然后在
现在已经支持QQ微博GoogleGitHubFacebook登录需要在其对应的开放平台申请oauth登录权限然后在
**后台->Oauth** 配置中新增配置,填写对应的`appkey`和`appsecret`以及回调地址。
### 回调地址示例:
qqhttp://你的域名/oauth/authorize?type=qq

@ -2,6 +2,7 @@ from django.shortcuts import render
# Create your views here.
from urllib.parse import urlparse
import datetime
from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import get_user_model
@ -70,7 +71,7 @@ def authorize(request):
return HttpResponseRedirect(manager.get_authorization_url(nexturl))
user = manager.get_oauth_userinfo()
if user:
if not user.nikename:
if not user.nikename.strip():
import datetime
user.nikename = "djangoblog" + datetime.datetime.now().strftime('%y%m%d%I%M%S')
try:
@ -96,6 +97,7 @@ def authorize(request):
author = result[0]
if result[1]:
author.username = user.nikename
author.source = 'authorize'
author.save()
user.author = author
@ -127,7 +129,9 @@ def emailconfirm(request, id, sign):
result = get_user_model().objects.get_or_create(email=oauthuser.email)
author = result[0]
if result[1]:
author.username = oauthuser.nikename
author.source = 'emailconfirm'
author.username = oauthuser.nikename.strip() if oauthuser.nikename.strip() else "djangoblog" + datetime.datetime.now().strftime(
'%y%m%d%I%M%S')
author.save()
oauthuser.author = author
oauthuser.save()

@ -1,27 +1,26 @@
appdirs==1.4.3
asn1crypto==0.24.0
astroid==2.2.5
bottle==0.12.16
bottle==0.12.17
certifi==2019.6.16
cffi==1.12.3
chardet==3.0.4
colorama==0.4.1
coverage==4.5.3
cryptography==2.7
Django==2.2.2
Django==2.2.3
django-appconf==1.0.3
django-autoslug==1.9.4
django-compressor==2.3
django-debug-toolbar==1.11
django-debug-toolbar==2.0
django-haystack==2.8.1
django-ipware==2.1.0
django-mdeditor==0.1.14
django-uuslug==1.1.8
elasticsearch==7.0.2
elasticsearch==7.0.0
elasticsearch-dsl==7.0.0
idna==2.8
ipaddress==1.0.22
isort==4.3.20
isort==4.3.21
jieba==0.39
jsonpickle==1.2
lazy-object-proxy==1.4.1
@ -48,11 +47,11 @@ rjsmin==1.1.0
six==1.12.0
sqlparse==0.3.0
text-unidecode==1.2
typed-ast==1.4.0
Unidecode==1.1.0
typed-ast==1.3.1
Unidecode==1.1.1
urllib3==1.25.3
webencodings==0.5.1
WeRoBot==1.9.0
Whoosh==2.7.4
wrapt==1.11.1
wrapt==1.11.2
xmltodict==0.12.0

@ -1,27 +1,26 @@
appdirs==1.4.3
asn1crypto==0.24.0
astroid==2.2.5
bottle==0.12.16
bottle==0.12.17
certifi==2019.6.16
cffi==1.12.3
chardet==3.0.4
colorama==0.4.1
coverage==4.5.3
cryptography==2.7
Django==2.2.2
Django==2.2.3
django-appconf==1.0.3
django-autoslug==1.9.4
django-compressor==2.3
django-debug-toolbar==1.11
django-debug-toolbar==2.0
django-haystack==2.8.1
django-ipware==2.1.0
django-mdeditor==0.1.14
django-uuslug==1.1.8
elasticsearch==7.0.2
elasticsearch==7.0.0
elasticsearch-dsl==7.0.0
idna==2.8
ipaddress==1.0.22
isort==4.3.20
isort==4.3.21
jieba==0.39
jsonpickle==1.2
lazy-object-proxy==1.4.1
@ -47,11 +46,11 @@ rjsmin==1.1.0
six==1.12.0
sqlparse==0.3.0
text-unidecode==1.2
typed-ast==1.4.0
Unidecode==1.1.0
typed-ast==1.3.1
Unidecode==1.1.1
urllib3==1.25.3
webencodings==0.5.1
WeRoBot==1.9.0
Whoosh==2.7.4
wrapt==1.11.1
wrapt==1.11.2
xmltodict==0.12.0

Loading…
Cancel
Save