增加多语言支持

This commit is contained in:
liangliangyy
2023-09-08 00:24:28 +08:00
parent c582f44ba0
commit 442a03ffdc
50 changed files with 2905 additions and 324 deletions

View File

@@ -1,7 +1,8 @@
FROM python:3
ENV PYTHONUNBUFFERED 1
WORKDIR /code/djangoblog/
RUN apt-get install default-libmysqlclient-dev -y && \
RUN apt-get update && \
apt-get install default-libmysqlclient-dev gettext -y && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ADD requirements.txt requirements.txt
RUN pip install --upgrade pip && \

View File

@@ -10,8 +10,8 @@ from .models import BlogUser
class BlogUserCreationForm(forms.ModelForm):
password1 = forms.CharField(label='密码', widget=forms.PasswordInput)
password2 = forms.CharField(label='再次输入密码', widget=forms.PasswordInput)
password1 = forms.CharField(label=_('password'), widget=forms.PasswordInput)
password2 = forms.CharField(label=_('Enter password again'), widget=forms.PasswordInput)
class Meta:
model = BlogUser
@@ -22,7 +22,7 @@ class BlogUserCreationForm(forms.ModelForm):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("两次密码不一致")
raise forms.ValidationError(_("passwords do not match"))
return password2
def save(self, commit=True):

View File

@@ -3,7 +3,7 @@ from django.contrib.auth import get_user_model, password_validation
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.core.exceptions import ValidationError
from django.forms import widgets
from django.utils.translation import gettext_lazy as _
from . import utils
from .models import BlogUser
@@ -33,7 +33,7 @@ class RegisterForm(UserCreationForm):
def clean_email(self):
email = self.cleaned_data['email']
if get_user_model().objects.filter(email=email).exists():
raise ValidationError("该邮箱已经存在.")
raise ValidationError(_("email already exists"))
return email
class Meta:
@@ -43,11 +43,11 @@ class RegisterForm(UserCreationForm):
class ForgetPasswordForm(forms.Form):
new_password1 = forms.CharField(
label="新密码",
label=_("New password"),
widget=forms.PasswordInput(
attrs={
"class": "form-control",
'placeholder': "密码"
'placeholder': _("New password")
}
),
)
@@ -57,7 +57,7 @@ class ForgetPasswordForm(forms.Form):
widget=forms.PasswordInput(
attrs={
"class": "form-control",
'placeholder': "确认密码"
'placeholder': _("Confirm password")
}
),
)
@@ -67,17 +67,17 @@ class ForgetPasswordForm(forms.Form):
widget=forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': "邮箱"
'placeholder': _("Email")
}
),
)
code = forms.CharField(
label='验证码',
label=_('Code'),
widget=forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': "验证码"
'placeholder': _("Code")
}
),
)
@@ -86,7 +86,7 @@ class ForgetPasswordForm(forms.Form):
password1 = self.data.get("new_password1")
password2 = self.data.get("new_password2")
if password1 and password2 and password1 != password2:
raise ValidationError("两次密码不一致")
raise ValidationError(_("passwords do not match"))
password_validation.validate_password(password2)
return password2
@@ -97,7 +97,7 @@ class ForgetPasswordForm(forms.Form):
email=user_email
).exists():
# todo 这里的报错提示可以判断一个邮箱是不是注册过,如果不想暴露可以修改
raise ValidationError("未找到邮箱对应的用户")
raise ValidationError(_("email does not exist"))
return user_email
def clean_code(self):
@@ -113,5 +113,5 @@ class ForgetPasswordForm(forms.Form):
class ForgetPasswordCodeForm(forms.Form):
email = forms.EmailField(
label="邮箱号"
label=_('Email'),
)

View File

@@ -0,0 +1,46 @@
# Generated by Django 4.2.5 on 2023-09-06 13:13
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='bloguser',
options={'get_latest_by': 'id', 'ordering': ['-id'], 'verbose_name': 'user', 'verbose_name_plural': 'user'},
),
migrations.RemoveField(
model_name='bloguser',
name='created_time',
),
migrations.RemoveField(
model_name='bloguser',
name='last_mod_time',
),
migrations.AddField(
model_name='bloguser',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='bloguser',
name='last_modify_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'),
),
migrations.AlterField(
model_name='bloguser',
name='nickname',
field=models.CharField(blank=True, max_length=100, verbose_name='nick name'),
),
migrations.AlterField(
model_name='bloguser',
name='source',
field=models.CharField(blank=True, max_length=100, verbose_name='create source'),
),
]

View File

@@ -2,17 +2,17 @@ from django.contrib.auth.models import AbstractUser
from django.db import models
from django.urls import reverse
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from djangoblog.utils import get_current_site
# Create your models here.
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)
nickname = models.CharField(_('nick name'), max_length=100, blank=True)
creation_time = models.DateTimeField(_('creation time'), default=now)
last_modify_time = models.DateTimeField(_('last modify time'), default=now)
source = models.CharField(_('create source'), max_length=100, blank=True)
def get_absolute_url(self):
return reverse(
@@ -30,6 +30,6 @@ class BlogUser(AbstractUser):
class Meta:
ordering = ['-id']
verbose_name = "用户"
verbose_name = _('user')
verbose_name_plural = verbose_name
get_latest_by = 'id'

View File

@@ -1,11 +1,11 @@
from django.conf import settings
from django.test import Client, RequestFactory, TestCase
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from djangoblog.utils import *
from accounts.models import BlogUser
from blog.models import Article, Category
from djangoblog.utils import *
from . import utils
@@ -39,8 +39,8 @@ class AccountTest(TestCase):
category = Category()
category.name = "categoryaaa"
category.created_time = timezone.now()
category.last_mod_time = timezone.now()
category.creation_time = timezone.now()
category.last_modify_time = timezone.now()
category.save()
article = Article()
@@ -86,8 +86,8 @@ class AccountTest(TestCase):
delete_sidebar_cache()
category = Category()
category.name = "categoryaaa"
category.created_time = timezone.now()
category.last_mod_time = timezone.now()
category.creation_time = timezone.now()
category.last_modify_time = timezone.now()
category.save()
article = Article()
@@ -191,7 +191,7 @@ class AccountTest(TestCase):
response=resp,
form="form",
field="email",
errors="未找到邮箱对应的用户"
errors=_("email does not exist")
)
def test_forget_password_email_code_error(self):
@@ -213,5 +213,5 @@ class AccountTest(TestCase):
response=resp,
form="form",
field="code",
errors="验证码错误"
errors=_('Verification code error')
)

View File

@@ -1,5 +1,5 @@
from django.urls import include, re_path
from django.urls import path
from django.urls import re_path
from . import views
from .forms import LoginForm
@@ -7,22 +7,22 @@ from .forms import LoginForm
app_name = "accounts"
urlpatterns = [re_path(r'^login/$',
views.LoginView.as_view(success_url='/'),
name='login',
kwargs={'authentication_form': LoginForm}),
views.LoginView.as_view(success_url='/'),
name='login',
kwargs={'authentication_form': LoginForm}),
re_path(r'^register/$',
views.RegisterView.as_view(success_url="/"),
name='register'),
views.RegisterView.as_view(success_url="/"),
name='register'),
re_path(r'^logout/$',
views.LogoutView.as_view(),
name='logout'),
views.LogoutView.as_view(),
name='logout'),
path(r'account/result.html',
views.account_result,
name='result'),
re_path(r'^forget_password/$',
views.ForgetPasswordView.as_view(),
name='forget_password'),
views.ForgetPasswordView.as_view(),
name='forget_password'),
re_path(r'^forget_password_code/$',
views.ForgetPasswordEmailCode.as_view(),
name='forget_password_code'),
views.ForgetPasswordEmailCode.as_view(),
name='forget_password_code'),
]

View File

@@ -2,20 +2,23 @@ import typing
from datetime import timedelta
from django.core.cache import cache
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext
from djangoblog.utils import send_email
_code_ttl = timedelta(minutes=5)
def send_verify_email(to_mail: str, code: str, subject: str = "邮件验证码"):
def send_verify_email(to_mail: str, code: str, subject: str = _("Verify Email")):
"""发送重设密码验证码
Args:
to_mail: 接受邮箱
subject: 邮件主题
code: 验证码
"""
html_content = f"您正在重设密码,验证码为:{code}, 5分钟内有效请妥善保管"
html_content = _(
f"You are resetting the password, the verification code is{code}, valid within 5 minutes, please keep it properly")
send_email([to_mail], subject, html_content)
@@ -32,7 +35,7 @@ def verify(email: str, code: str) -> typing.Optional[str]:
"""
cache_code = get_code(email)
if cache_code != code:
return "验证码错误"
return gettext("Verification code error")
def set_code(email: str, code: str):

View File

@@ -1,5 +1,5 @@
import logging
from django.utils.translation import gettext_lazy as _
from django.conf import settings
from django.contrib import auth
from django.contrib.auth import REDIRECT_FIELD_NAME

View File

@@ -10,7 +10,7 @@ from .models import Article
class ArticleListFilter(admin.SimpleListFilter):
title = _("作者")
title = _("author")
parameter_name = 'author'
def lookups(self, request, model_admin):
@@ -50,10 +50,10 @@ def open_article_commentstatus(modeladmin, request, queryset):
queryset.update(comment_status='o')
makr_article_publish.short_description = '发布选中文章'
draft_article.short_description = '选中文章设置为草稿'
close_article_commentstatus.short_description = '关闭文章评论'
open_article_commentstatus.short_description = '打开文章评论'
makr_article_publish.short_description = _('Publish selected articles')
draft_article.short_description = _('Draft selected articles')
close_article_commentstatus.short_description = _('Close article comments')
open_article_commentstatus.short_description = _('Open article comments')
class ArticlelAdmin(admin.ModelAdmin):
@@ -65,7 +65,7 @@ class ArticlelAdmin(admin.ModelAdmin):
'title',
'author',
'link_to_category',
'created_time',
'creation_time',
'views',
'status',
'type',
@@ -73,7 +73,7 @@ class ArticlelAdmin(admin.ModelAdmin):
list_display_links = ('id', 'title')
list_filter = (ArticleListFilter, 'status', 'type', 'category', 'tags')
filter_horizontal = ('tags',)
exclude = ('created_time', 'last_mod_time')
exclude = ('creation_time', 'last_modify_time')
view_on_site = True
actions = [
makr_article_publish,
@@ -86,7 +86,7 @@ class ArticlelAdmin(admin.ModelAdmin):
link = reverse('admin:%s_%s_change' % info, args=(obj.category.id,))
return format_html(u'<a href="%s">%s</a>' % (link, obj.category.name))
link_to_category.short_description = '分类目录'
link_to_category.short_description = _('category')
def get_form(self, request, obj=None, **kwargs):
form = super(ArticlelAdmin, self).get_form(request, obj, **kwargs)
@@ -108,21 +108,21 @@ class ArticlelAdmin(admin.ModelAdmin):
class TagAdmin(admin.ModelAdmin):
exclude = ('slug', 'last_mod_time', 'created_time')
exclude = ('slug', 'last_mod_time', 'creation_time')
class CategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'parent_category', 'index')
exclude = ('slug', 'last_mod_time', 'created_time')
exclude = ('slug', 'last_mod_time', 'creation_time')
class LinksAdmin(admin.ModelAdmin):
exclude = ('last_mod_time', 'created_time')
exclude = ('last_mod_time', 'creation_time')
class SideBarAdmin(admin.ModelAdmin):
list_display = ('name', 'content', 'is_enable', 'sequence')
exclude = ('last_mod_time', 'created_time')
exclude = ('last_mod_time', 'creation_time')
class BlogSettingsAdmin(admin.ModelAdmin):

View File

@@ -0,0 +1,300 @@
# Generated by Django 4.2.5 on 2023-09-06 13:13
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import mdeditor.fields
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('blog', '0004_rename_analyticscode_blogsettings_analytics_code_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='article',
options={'get_latest_by': 'id', 'ordering': ['-article_order', '-pub_time'], 'verbose_name': 'article', 'verbose_name_plural': 'article'},
),
migrations.AlterModelOptions(
name='category',
options={'ordering': ['-index'], 'verbose_name': 'category', 'verbose_name_plural': 'category'},
),
migrations.AlterModelOptions(
name='links',
options={'ordering': ['sequence'], 'verbose_name': 'link', 'verbose_name_plural': 'link'},
),
migrations.AlterModelOptions(
name='sidebar',
options={'ordering': ['sequence'], 'verbose_name': 'sidebar', 'verbose_name_plural': 'sidebar'},
),
migrations.AlterModelOptions(
name='tag',
options={'ordering': ['name'], 'verbose_name': 'tag', 'verbose_name_plural': 'tag'},
),
migrations.RemoveField(
model_name='article',
name='created_time',
),
migrations.RemoveField(
model_name='article',
name='last_mod_time',
),
migrations.RemoveField(
model_name='category',
name='created_time',
),
migrations.RemoveField(
model_name='category',
name='last_mod_time',
),
migrations.RemoveField(
model_name='links',
name='created_time',
),
migrations.RemoveField(
model_name='sidebar',
name='created_time',
),
migrations.RemoveField(
model_name='tag',
name='created_time',
),
migrations.RemoveField(
model_name='tag',
name='last_mod_time',
),
migrations.AddField(
model_name='article',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='article',
name='last_modify_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'),
),
migrations.AddField(
model_name='category',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='category',
name='last_modify_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'),
),
migrations.AddField(
model_name='links',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='sidebar',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='tag',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='tag',
name='last_modify_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'),
),
migrations.AlterField(
model_name='article',
name='article_order',
field=models.IntegerField(default=0, verbose_name='order'),
),
migrations.AlterField(
model_name='article',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='author'),
),
migrations.AlterField(
model_name='article',
name='body',
field=mdeditor.fields.MDTextField(verbose_name='body'),
),
migrations.AlterField(
model_name='article',
name='category',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='category'),
),
migrations.AlterField(
model_name='article',
name='comment_status',
field=models.CharField(choices=[('o', 'Open'), ('c', 'Close')], default='o', max_length=1, verbose_name='comment status'),
),
migrations.AlterField(
model_name='article',
name='pub_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='publish time'),
),
migrations.AlterField(
model_name='article',
name='show_toc',
field=models.BooleanField(default=False, verbose_name='show toc'),
),
migrations.AlterField(
model_name='article',
name='status',
field=models.CharField(choices=[('d', 'Draft'), ('p', 'Published')], default='p', max_length=1, verbose_name='status'),
),
migrations.AlterField(
model_name='article',
name='tags',
field=models.ManyToManyField(blank=True, to='blog.tag', verbose_name='tag'),
),
migrations.AlterField(
model_name='article',
name='title',
field=models.CharField(max_length=200, unique=True, verbose_name='title'),
),
migrations.AlterField(
model_name='article',
name='type',
field=models.CharField(choices=[('a', 'Article'), ('p', 'Page')], default='a', max_length=1, verbose_name='type'),
),
migrations.AlterField(
model_name='article',
name='views',
field=models.PositiveIntegerField(default=0, verbose_name='views'),
),
migrations.AlterField(
model_name='blogsettings',
name='article_comment_count',
field=models.IntegerField(default=5, verbose_name='article comment count'),
),
migrations.AlterField(
model_name='blogsettings',
name='article_sub_length',
field=models.IntegerField(default=300, verbose_name='article sub length'),
),
migrations.AlterField(
model_name='blogsettings',
name='google_adsense_codes',
field=models.TextField(blank=True, default='', max_length=2000, null=True, verbose_name='adsense code'),
),
migrations.AlterField(
model_name='blogsettings',
name='open_site_comment',
field=models.BooleanField(default=True, verbose_name='open site comment'),
),
migrations.AlterField(
model_name='blogsettings',
name='show_google_adsense',
field=models.BooleanField(default=False, verbose_name='show adsense'),
),
migrations.AlterField(
model_name='blogsettings',
name='sidebar_article_count',
field=models.IntegerField(default=10, verbose_name='sidebar article count'),
),
migrations.AlterField(
model_name='blogsettings',
name='sidebar_comment_count',
field=models.IntegerField(default=5, verbose_name='sidebar comment count'),
),
migrations.AlterField(
model_name='blogsettings',
name='site_description',
field=models.TextField(default='', max_length=1000, verbose_name='site description'),
),
migrations.AlterField(
model_name='blogsettings',
name='site_keywords',
field=models.TextField(default='', max_length=1000, verbose_name='site keywords'),
),
migrations.AlterField(
model_name='blogsettings',
name='site_name',
field=models.CharField(default='', max_length=200, verbose_name='site name'),
),
migrations.AlterField(
model_name='blogsettings',
name='site_seo_description',
field=models.TextField(default='', max_length=1000, verbose_name='site seo description'),
),
migrations.AlterField(
model_name='category',
name='index',
field=models.IntegerField(default=0, verbose_name='index'),
),
migrations.AlterField(
model_name='category',
name='name',
field=models.CharField(max_length=30, unique=True, verbose_name='category name'),
),
migrations.AlterField(
model_name='category',
name='parent_category',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='blog.category', verbose_name='parent category'),
),
migrations.AlterField(
model_name='links',
name='is_enable',
field=models.BooleanField(default=True, verbose_name='is show'),
),
migrations.AlterField(
model_name='links',
name='last_mod_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'),
),
migrations.AlterField(
model_name='links',
name='link',
field=models.URLField(verbose_name='link'),
),
migrations.AlterField(
model_name='links',
name='name',
field=models.CharField(max_length=30, unique=True, verbose_name='link name'),
),
migrations.AlterField(
model_name='links',
name='sequence',
field=models.IntegerField(unique=True, verbose_name='order'),
),
migrations.AlterField(
model_name='links',
name='show_type',
field=models.CharField(choices=[('i', 'index'), ('l', 'list'), ('p', 'post'), ('a', 'all'), ('s', 'slide')], default='i', max_length=1, verbose_name='show type'),
),
migrations.AlterField(
model_name='sidebar',
name='content',
field=models.TextField(verbose_name='content'),
),
migrations.AlterField(
model_name='sidebar',
name='is_enable',
field=models.BooleanField(default=True, verbose_name='is enable'),
),
migrations.AlterField(
model_name='sidebar',
name='last_mod_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='modify time'),
),
migrations.AlterField(
model_name='sidebar',
name='name',
field=models.CharField(max_length=100, verbose_name='title'),
),
migrations.AlterField(
model_name='sidebar',
name='sequence',
field=models.IntegerField(unique=True, verbose_name='order'),
),
migrations.AlterField(
model_name='tag',
name='name',
field=models.CharField(max_length=30, unique=True, verbose_name='tag name'),
),
]

View File

@@ -17,17 +17,17 @@ logger = logging.getLogger(__name__)
class LinkShowType(models.TextChoices):
I = ('i', '首页')
L = ('l', '列表页')
P = ('p', '文章页面')
A = ('a', '全站')
S = ('s', '友情链接页面')
I = ('i', _('index'))
L = ('l', _('list'))
P = ('p', _('post'))
A = ('a', _('all'))
S = ('s', _('slide'))
class BaseModel(models.Model):
id = models.AutoField(primary_key=True)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
creation_time = models.DateTimeField(_('creation time'), default=now)
last_modify_time = models.DateTimeField(_('modify time'), default=now)
def save(self, *args, **kwargs):
is_update_views = isinstance(
@@ -60,49 +60,49 @@ class BaseModel(models.Model):
class Article(BaseModel):
"""文章"""
STATUS_CHOICES = (
('d', '草稿'),
('p', '发表'),
('d', _('Draft')),
('p', _('Published')),
)
COMMENT_STATUS = (
('o', '打开'),
('c', '关闭'),
('o', _('Open')),
('c', _('Close')),
)
TYPE = (
('a', '文章'),
('p', '页面'),
('a', _('Article')),
('p', _('Page')),
)
title = models.CharField('标题', max_length=200, unique=True)
body = MDTextField('正文')
title = models.CharField(_('title'), max_length=200, unique=True)
body = MDTextField(_('body'))
pub_time = models.DateTimeField(
'发布时间', blank=False, null=False, default=now)
_('publish time'), blank=False, null=False, default=now)
status = models.CharField(
'文章状态',
_('status'),
max_length=1,
choices=STATUS_CHOICES,
default='p')
comment_status = models.CharField(
'评论状态',
_('comment status'),
max_length=1,
choices=COMMENT_STATUS,
default='o')
type = models.CharField('类型', max_length=1, choices=TYPE, default='a')
views = models.PositiveIntegerField('浏览量', default=0)
type = models.CharField(_('type'), max_length=1, choices=TYPE, default='a')
views = models.PositiveIntegerField(_('views'), default=0)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name='作者',
verbose_name=_('author'),
blank=False,
null=False,
on_delete=models.CASCADE)
article_order = models.IntegerField(
'排序,数字越大越靠前', blank=False, null=False, default=0)
show_toc = models.BooleanField("是否显示toc目录", blank=False, null=False, default=False)
_('order'), blank=False, null=False, default=0)
show_toc = models.BooleanField(_('show toc'), blank=False, null=False, default=False)
category = models.ForeignKey(
'Category',
verbose_name='分类',
verbose_name=_('category'),
on_delete=models.CASCADE,
blank=False,
null=False)
tags = models.ManyToManyField('Tag', verbose_name='标签集合', blank=True)
tags = models.ManyToManyField('Tag', verbose_name=_('tag'), blank=True)
def body_to_string(self):
return self.body
@@ -112,16 +112,16 @@ class Article(BaseModel):
class Meta:
ordering = ['-article_order', '-pub_time']
verbose_name = "文章"
verbose_name = _('article')
verbose_name_plural = verbose_name
get_latest_by = 'id'
def get_absolute_url(self):
return reverse('blog:detailbyid', kwargs={
'article_id': self.id,
'year': self.created_time.year,
'month': self.created_time.month,
'day': self.created_time.day
'year': self.creation_time.year,
'month': self.creation_time.month,
'day': self.creation_time.day
})
@cache_decorator(60 * 60 * 10)
@@ -168,19 +168,19 @@ class Article(BaseModel):
class Category(BaseModel):
"""文章分类"""
name = models.CharField('分类名', max_length=30, unique=True)
name = models.CharField(_('category name'), max_length=30, unique=True)
parent_category = models.ForeignKey(
'self',
verbose_name="父级分类",
verbose_name=_('parent category'),
blank=True,
null=True,
on_delete=models.CASCADE)
slug = models.SlugField(default='no-slug', max_length=60, blank=True)
index = models.IntegerField(default=0, verbose_name="权重排序-越大越靠前")
index = models.IntegerField(default=0, verbose_name=_('index'))
class Meta:
ordering = ['-index']
verbose_name = "分类"
verbose_name = _('category')
verbose_name_plural = verbose_name
def get_absolute_url(self):
@@ -231,7 +231,7 @@ class Category(BaseModel):
class Tag(BaseModel):
"""文章标签"""
name = models.CharField('标签名', max_length=30, unique=True)
name = models.CharField(_('tag name'), max_length=30, unique=True)
slug = models.SlugField(default='no-slug', max_length=60, blank=True)
def __str__(self):
@@ -246,29 +246,29 @@ class Tag(BaseModel):
class Meta:
ordering = ['name']
verbose_name = "标签"
verbose_name = _('tag')
verbose_name_plural = verbose_name
class Links(models.Model):
"""友情链接"""
name = models.CharField('链接名称', max_length=30, unique=True)
link = models.URLField('链接地址')
sequence = models.IntegerField('排序', unique=True)
name = models.CharField(_('link name'), max_length=30, unique=True)
link = models.URLField(_('link'))
sequence = models.IntegerField(_('order'), unique=True)
is_enable = models.BooleanField(
'是否显示', default=True, blank=False, null=False)
_('is show'), default=True, blank=False, null=False)
show_type = models.CharField(
'显示类型',
_('show type'),
max_length=1,
choices=LinkShowType.choices,
default=LinkShowType.I)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
creation_time = models.DateTimeField(_('creation time'), default=now)
last_mod_time = models.DateTimeField(_('modify time'), default=now)
class Meta:
ordering = ['sequence']
verbose_name = '友情链接'
verbose_name = _('link')
verbose_name_plural = verbose_name
def __str__(self):
@@ -277,16 +277,16 @@ class Links(models.Model):
class SideBar(models.Model):
"""侧边栏,可以展示一些html内容"""
name = models.CharField('标题', max_length=100)
content = models.TextField("内容")
sequence = models.IntegerField('排序', unique=True)
is_enable = models.BooleanField('是否启用', default=True)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
name = models.CharField(_('title'), max_length=100)
content = models.TextField(_('content'))
sequence = models.IntegerField(_('order'), unique=True)
is_enable = models.BooleanField(_('is enable'), default=True)
creation_time = models.DateTimeField(_('creation time'), default=now)
last_mod_time = models.DateTimeField(_('modify time'), default=now)
class Meta:
ordering = ['sequence']
verbose_name = '侧边栏'
verbose_name = _('sidebar')
verbose_name_plural = verbose_name
def __str__(self):
@@ -296,33 +296,33 @@ class SideBar(models.Model):
class BlogSettings(models.Model):
"""blog的配置"""
site_name = models.CharField(
"网站名称",
_('site name'),
max_length=200,
null=False,
blank=False,
default='')
site_description = models.TextField(
"网站描述",
_('site description'),
max_length=1000,
null=False,
blank=False,
default='')
site_seo_description = models.TextField(
"网站SEO描述", max_length=1000, null=False, blank=False, default='')
_('site seo description'), max_length=1000, null=False, blank=False, default='')
site_keywords = models.TextField(
"网站关键字",
_('site keywords'),
max_length=1000,
null=False,
blank=False,
default='')
article_sub_length = models.IntegerField("文章摘要长度", default=300)
sidebar_article_count = models.IntegerField("侧边栏文章数目", default=10)
sidebar_comment_count = models.IntegerField("侧边栏评论数目", default=5)
article_comment_count = models.IntegerField("文章页面默认显示评论数目", default=5)
show_google_adsense = models.BooleanField('是否显示谷歌广告', default=False)
article_sub_length = models.IntegerField(_('article sub length'), default=300)
sidebar_article_count = models.IntegerField(_('sidebar article count'), default=10)
sidebar_comment_count = models.IntegerField(_('sidebar comment count'), default=5)
article_comment_count = models.IntegerField(_('article comment count'), default=5)
show_google_adsense = models.BooleanField(_('show adsense'), default=False)
google_adsense_codes = models.TextField(
'广告内容', max_length=2000, null=True, blank=True, default='')
open_site_comment = models.BooleanField('是否打开网站评论功能', default=True)
_('adsense code'), max_length=2000, null=True, blank=True, default='')
open_site_comment = models.BooleanField(_('open site comment'), default=True)
global_header = models.TextField("公共头部", null=True, blank=True, default='')
global_footer = models.TextField("公共尾部", null=True, blank=True, default='')
beian_code = models.CharField(

View File

@@ -42,7 +42,7 @@ function debounce(func, wait) {
clearTimeout(timeout);
timeout = setTimeout(func, wait);
};
};
}
function slideTopSet() {
var top = $(document).scrollTop();

View File

@@ -161,7 +161,7 @@
if (!n) {
return NProgress.start();
} else if(n > 1) {
return;
} else {
if (typeof amount !== 'number') {
if (n >= 0 && n < 0.2) { amount = 0.1; }

View File

@@ -146,7 +146,7 @@ def load_sidebar(user, linktype):
is_enable=True).order_by('sequence')
most_read_articles = Article.objects.filter(status='p').order_by(
'-views')[:blogsetting.sidebar_article_count]
dates = Article.objects.datetimes('created_time', 'month', order='DESC')
dates = Article.objects.datetimes('creation_time', 'month', order='DESC')
links = Links.objects.filter(is_enable=True).filter(
Q(show_type=str(linktype)) | Q(show_type=LinkShowType.A))
commment_list = Comment.objects.filter(is_enable=True).order_by(

View File

@@ -46,7 +46,7 @@ class ArticleTest(TestCase):
category = Category()
category.name = "category"
category.created_time = timezone.now()
category.creation_time = timezone.now()
category.last_mod_time = timezone.now()
category.save()
@@ -105,19 +105,19 @@ class ArticleTest(TestCase):
response = self.client.get(reverse('blog:archives'))
self.assertEqual(response.status_code, 200)
p = Paginator(Article.objects.all(), 2)
self.__check_pagination__(p, '', '')
p = Paginator(Article.objects.all(), settings.PAGINATE_BY)
self.check_pagination(p, '', '')
p = Paginator(Article.objects.filter(tags=tag), 2)
self.__check_pagination__(p, '分类标签归档', tag.slug)
p = Paginator(Article.objects.filter(tags=tag), settings.PAGINATE_BY)
self.check_pagination(p, '分类标签归档', tag.slug)
p = Paginator(
Article.objects.filter(
author__username='liangliangyy'), 2)
self.__check_pagination__(p, '作者文章归档', 'liangliangyy')
author__username='liangliangyy'), settings.PAGINATE_BY)
self.check_pagination(p, '作者文章归档', 'liangliangyy')
p = Paginator(Article.objects.filter(category=category), 2)
self.__check_pagination__(p, '分类目录归档', category.slug)
p = Paginator(Article.objects.filter(category=category), settings.PAGINATE_BY)
self.check_pagination(p, '分类目录归档', category.slug)
f = BlogSearchForm()
f.search()
@@ -148,20 +148,16 @@ class ArticleTest(TestCase):
self.client.get('/admin/admin/logentry/')
self.client.get('/admin/admin/logentry/1/change/')
def __check_pagination__(self, p, type, value):
s = load_pagination_info(p.page(1), type, value)
self.assertIsNotNone(s)
response = self.client.get(s['previous_url'])
self.assertEqual(response.status_code, 200)
response = self.client.get(s['next_url'])
self.assertEqual(response.status_code, 200)
s = load_pagination_info(p.page(2), type, value)
self.assertIsNotNone(s)
response = self.client.get(s['previous_url'])
self.assertEqual(response.status_code, 200)
response = self.client.get(s['next_url'])
self.assertEqual(response.status_code, 200)
def check_pagination(self, p, type, value):
for page in range(1, p.num_pages + 1):
s = load_pagination_info(p.page(page), type, value)
self.assertIsNotNone(s)
if s['previous_url']:
response = self.client.get(s['previous_url'])
self.assertEqual(response.status_code, 200)
if s['next_url']:
response = self.client.get(s['next_url'])
self.assertEqual(response.status_code, 200)
def test_image(self):
import requests

View File

@@ -9,6 +9,7 @@ from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django.templatetags.static import static
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
@@ -93,6 +94,11 @@ class IndexView(ArticleListView):
# 友情链接类型
link_type = LinkShowType.I
def dispatch(self, request, *args, **kwargs):
from django.utils.translation import get_language
print(get_language())
return super(IndexView, self).dispatch(request, *args, **kwargs)
def get_queryset_data(self):
article_list = Article.objects.filter(type='a', status='p')
return article_list
@@ -344,7 +350,7 @@ def page_not_found_view(
url = request.get_full_path()
return render(request,
template_name,
{'message': '哎呀,您访问的地址 ' + url + ' 是一个未知的地方。请点击首页看看别的?',
{'message': _('Sorry, the page you requested is not found, please click the home page to see other?'),
'statuscode': '404'},
status=404)
@@ -352,7 +358,7 @@ def page_not_found_view(
def server_error_view(request, template_name='blog/error_page.html'):
return render(request,
template_name,
{'message': '哎呀,出错了,我已经收集到了错误信息,之后会抓紧抢修,请点击首页看看别的?',
{'message': _('Sorry, the server is busy, please click the home page to see other?'),
'statuscode': '500'},
status=500)
@@ -365,4 +371,5 @@ def permission_denied_view(
logger.error(exception)
return render(
request, template_name, {
'message': '哎呀,您没有权限访问此页面,请点击首页看看别的?', 'statuscode': '403'}, status=403)
'message': _('Sorry, you do not have permission to access this page?'),
'statuscode': '403'}, status=403)

View File

@@ -1,7 +1,7 @@
from django.contrib import admin
# Register your models here.
from django.urls import reverse
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
def disable_commentstatus(modeladmin, request, queryset):
@@ -12,8 +12,8 @@ def enable_commentstatus(modeladmin, request, queryset):
queryset.update(is_enable=True)
disable_commentstatus.short_description = '禁用评论'
enable_commentstatus.short_description = '启用评论'
disable_commentstatus.short_description = _('Disable comments')
enable_commentstatus.short_description = _('Enable comments')
class CommentAdmin(admin.ModelAdmin):
@@ -24,10 +24,10 @@ class CommentAdmin(admin.ModelAdmin):
'link_to_userinfo',
'link_to_article',
'is_enable',
'created_time')
'creation_time')
list_display_links = ('id', 'body', 'is_enable')
list_filter = ('is_enable', 'author', 'article',)
exclude = ('created_time', 'last_mod_time')
exclude = ('creation_time', 'last_modify_time')
actions = [disable_commentstatus, enable_commentstatus]
def link_to_userinfo(self, obj):
@@ -43,5 +43,5 @@ class CommentAdmin(admin.ModelAdmin):
return format_html(
u'<a href="%s">%s</a>' % (link, obj.article.title))
link_to_userinfo.short_description = '用户'
link_to_article.short_description = '文章'
link_to_userinfo.short_description = _('User')
link_to_article.short_description = _('Article')

View File

@@ -0,0 +1,60 @@
# Generated by Django 4.2.5 on 2023-09-06 13:13
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('blog', '0005_alter_article_options_alter_category_options_and_more'),
('comments', '0002_alter_comment_is_enable'),
]
operations = [
migrations.AlterModelOptions(
name='comment',
options={'get_latest_by': 'id', 'ordering': ['-id'], 'verbose_name': 'comment', 'verbose_name_plural': 'comment'},
),
migrations.RemoveField(
model_name='comment',
name='created_time',
),
migrations.RemoveField(
model_name='comment',
name='last_mod_time',
),
migrations.AddField(
model_name='comment',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='comment',
name='last_modify_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'),
),
migrations.AlterField(
model_name='comment',
name='article',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='blog.article', verbose_name='article'),
),
migrations.AlterField(
model_name='comment',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='author'),
),
migrations.AlterField(
model_name='comment',
name='is_enable',
field=models.BooleanField(default=False, verbose_name='enable'),
),
migrations.AlterField(
model_name='comment',
name='parent_comment',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='comments.comment', verbose_name='parent comment'),
),
]

View File

@@ -1,6 +1,7 @@
from django.conf import settings
from django.db import models
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from blog.models import Article
@@ -9,28 +10,28 @@ from blog.models import Article
class Comment(models.Model):
body = models.TextField('正文', max_length=300)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
creation_time = models.DateTimeField(_('creation time'), default=now)
last_modify_time = models.DateTimeField(_('last modify time'), default=now)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name='作者',
verbose_name=_('author'),
on_delete=models.CASCADE)
article = models.ForeignKey(
Article,
verbose_name='文章',
verbose_name=_('article'),
on_delete=models.CASCADE)
parent_comment = models.ForeignKey(
'self',
verbose_name="上级评论",
verbose_name=_('parent comment'),
blank=True,
null=True,
on_delete=models.CASCADE)
is_enable = models.BooleanField(
'是否显示', default=False, blank=False, null=False)
is_enable = models.BooleanField(_('enable'),
default=False, blank=False, null=False)
class Meta:
ordering = ['-id']
verbose_name = "评论"
verbose_name = _('comment')
verbose_name_plural = verbose_name
get_latest_by = 'id'

View File

@@ -1,6 +1,5 @@
from django.test import Client, RequestFactory, TestCase
from django.test import Client, RequestFactory, TransactionTestCase
from django.urls import reverse
from django.utils import timezone
from accounts.models import BlogUser
from blog.models import Category, Article
@@ -11,7 +10,7 @@ from djangoblog.utils import get_max_articleid_commentid
# Create your tests here.
class CommentsTest(TestCase):
class CommentsTest(TransactionTestCase):
def setUp(self):
self.client = Client()
self.factory = RequestFactory()
@@ -20,6 +19,11 @@ class CommentsTest(TestCase):
value.comment_need_review = True
value.save()
self.user = BlogUser.objects.create_superuser(
email="liangliangyy1@gmail.com",
username="liangliangyy1",
password="liangliangyy1")
def update_article_comment_status(self, article):
comments = article.comment_set.all()
for comment in comments:
@@ -27,23 +31,16 @@ class CommentsTest(TestCase):
comment.save()
def test_validate_comment(self):
user = BlogUser.objects.create_superuser(
email="liangliangyy1@gmail.com",
username="liangliangyy1",
password="liangliangyy1")
self.client.login(username='liangliangyy1', password='liangliangyy1')
category = Category()
category.name = "categoryccc"
category.created_time = timezone.now()
category.last_mod_time = timezone.now()
category.save()
article = Article()
article.title = "nicetitleccc"
article.body = "nicecontentccc"
article.author = user
article.author = self.user
article.category = category
article.type = 'a'
article.status = 'p'

View File

@@ -1,5 +1,7 @@
import logging
from django.utils.translation import gettext_lazy as _
from djangoblog.utils import get_current_site
from djangoblog.utils import send_email
@@ -8,29 +10,28 @@ logger = logging.getLogger(__name__)
def send_comment_email(comment):
site = get_current_site().domain
subject = '感谢您发表的评论'
article_url = "https://{site}{path}".format(
site=site, path=comment.article.get_absolute_url())
html_content = """
<p>非常感谢您在本站发表评论</p>
您可以访问
<a href="%s" rel="bookmark">%s</a>
来查看您的评论,
再次感谢您!
<br />
如果上面链接无法打开,请将此链接复制至浏览器。
%s
""" % (article_url, comment.article.title, article_url)
subject = _('Thanks for your comment')
article_url = f"https://{site}{comment.article.get_absolute_url()}"
html_content = _(f"""
<p>Thank you very much for your comments on this site</p>
You can visit
<a href="{article_url}" rel="bookmark">{comment.article.title}</a>
to review your comments,
Thank you again!
<br />
If the link above cannot be opened, please copy this link to your browser.
{article_url}
""")
tomail = comment.author.email
send_email([tomail], subject, html_content)
try:
if comment.parent_comment:
html_content = """
您在 <a href="%s" rel="bookmark">%s</a> 的评论 <br/> %s <br/> 收到回复啦.快去看看吧
<br/>
如果上面链接无法打开,请将此链接复制至浏览器。
%s
""" % (article_url, comment.article.title, comment.parent_comment.body, article_url)
html_content = _(f"""
Your comment on <a href="{article_url}" rel="bookmark">{comment.article.title}</a><br/> {comment.parent_comment.body} <br/> has received a reply. go check it out
<br/>
If the link above cannot be opened, please copy this link to your browser.
{article_url}
""")
tomail = comment.parent_comment.author.email
send_email([tomail], subject, html_content)
except Exception as e:

View File

@@ -6,6 +6,7 @@ from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.views.generic.edit import FormView
from accounts.models import BlogUser
from blog.models import Article
from .forms import CommentForm
from .models import Comment
@@ -37,7 +38,7 @@ class CommentPostView(FormView):
def form_valid(self, form):
"""提交的数据验证合法后的逻辑"""
user = self.request.user
author = BlogUser.objects.get(pk=user.pk)
article_id = self.kwargs['article_id']
article = get_object_or_404(Article, pk=article_id)
@@ -49,7 +50,7 @@ class CommentPostView(FormView):
settings = get_blog_setting()
if not settings.comment_need_review:
comment.is_enable = True
comment.author = user
comment.author = author
if form.cleaned_data['parent_comment_id']:
parent_comment = Comment.objects.get(

View File

@@ -12,6 +12,8 @@ https://docs.djangoproject.com/en/1.10/ref/settings/
import os
import sys
from django.utils.translation import gettext_lazy as _
def env_to_bool(env, default):
str_val = os.environ.get(env)
@@ -62,8 +64,10 @@ INSTALLED_APPS = [
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.gzip.GZipMiddleware',
# 'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
@@ -132,8 +136,14 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGES = (
('en', _('English')),
('zh-hans', _('Simplified Chinese')),
('zh-hant', _('Traditional Chinese')),
)
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
LANGUAGE_CODE = 'zh-hans'
@@ -182,13 +192,13 @@ PAGINATE_BY = 10
# http cache timeout
CACHE_CONTROL_MAX_AGE = 2592000
# cache setting
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'TIMEOUT': 10800,
'LOCATION': 'unique-snowflake',
}
}
# CACHES = {
# 'default': {
# 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
# 'TIMEOUT': 10800,
# 'LOCATION': 'unique-snowflake',
# }
# }
# 使用redis作为缓存
if os.environ.get("DJANGO_REDIS_URL"):
CACHES = {

View File

@@ -23,7 +23,7 @@ class ArticleSiteMap(Sitemap):
return Article.objects.filter(status='p')
def lastmod(self, obj):
return obj.last_mod_time
return obj.last_modify_time
class CategorySiteMap(Sitemap):
@@ -34,7 +34,7 @@ class CategorySiteMap(Sitemap):
return Category.objects.all()
def lastmod(self, obj):
return obj.last_mod_time
return obj.last_modify_time
class TagSiteMap(Sitemap):
@@ -45,7 +45,7 @@ class TagSiteMap(Sitemap):
return Tag.objects.all()
def lastmod(self, obj):
return obj.last_mod_time
return obj.last_modify_time
class UserSiteMap(Sitemap):

View File

@@ -14,9 +14,10 @@ Including another URLconf
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf import settings
from django.conf.urls.i18n import i18n_patterns
from django.conf.urls.static import static
from django.contrib.sitemaps.views import sitemap
from django.urls import include
from django.urls import path, include
from django.urls import re_path
from haystack.views import search_view_factory
@@ -38,22 +39,26 @@ sitemaps = {
handler404 = 'blog.views.page_not_found_view'
handler500 = 'blog.views.server_error_view'
handle403 = 'blog.views.permission_denied_view'
urlpatterns = [
re_path(r'^admin/', admin_site.urls),
re_path(r'', include('blog.urls', namespace='blog')),
re_path(r'mdeditor/', include('mdeditor.urls')),
re_path(r'', include('comments.urls', namespace='comment')),
re_path(r'', include('accounts.urls', namespace='account')),
re_path(r'', include('oauth.urls', namespace='oauth')),
re_path(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
re_path(r'^feed/$', DjangoBlogFeed()),
re_path(r'^rss/$', DjangoBlogFeed()),
re_path('^search', search_view_factory(view_class=EsSearchView, form_class=ElasticSearchModelSearchForm),
name='search'),
re_path(r'', include('servermanager.urls', namespace='servermanager')),
re_path(r'', include('owntracks.urls', namespace='owntracks'))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
path('i18n/', include('django.conf.urls.i18n')),
]
urlpatterns += i18n_patterns(
re_path(r'^admin/', admin_site.urls),
re_path(r'', include('blog.urls', namespace='blog')),
re_path(r'mdeditor/', include('mdeditor.urls')),
re_path(r'', include('comments.urls', namespace='comment')),
re_path(r'', include('accounts.urls', namespace='account')),
re_path(r'', include('oauth.urls', namespace='oauth')),
re_path(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
re_path(r'^feed/$', DjangoBlogFeed()),
re_path(r'^rss/$', DjangoBlogFeed()),
re_path('^search', search_view_factory(view_class=EsSearchView, form_class=ElasticSearchModelSearchForm),
name='search'),
re_path(r'', include('servermanager.urls', namespace='servermanager')),
re_path(r'', include('owntracks.urls', namespace='owntracks'))
, prefix_default_language=True) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)

View File

@@ -0,0 +1,667 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-07 23:54+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\accounts\admin.py:13
msgid "password"
msgstr "password"
#: .\accounts\admin.py:14
msgid "Enter password again"
msgstr "Enter password again"
#: .\accounts\admin.py:25 .\accounts\forms.py:89
msgid "passwords do not match"
msgstr "passwords do not match"
#: .\accounts\admin.py:40
msgid "Password"
msgstr "Password"
#: .\accounts\admin.py:42
msgid ""
"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>."
msgstr ""
"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>."
#: .\accounts\forms.py:36
msgid "email already exists"
msgstr "email already exists"
#: .\accounts\forms.py:46 .\accounts\forms.py:50
#, fuzzy
#| msgid "forget the password"
msgid "New password"
msgstr "New password"
#: .\accounts\forms.py:60
#, fuzzy
#| msgid "forget the password"
msgid "Confirm password"
msgstr "Confirm the password"
#: .\accounts\forms.py:70 .\accounts\forms.py:116
msgid "Email"
msgstr "Email"
#: .\accounts\forms.py:76 .\accounts\forms.py:80
msgid "Code"
msgstr "Code"
#: .\accounts\forms.py:100 .\accounts\tests.py:194
msgid "email does not exist"
msgstr "email does not exist"
#: .\accounts\models.py:12
msgid "nick name"
msgstr "nick name"
#: .\accounts\models.py:13 .\blog\models.py:29 .\blog\models.py:266
#: .\blog\models.py:284 .\comments\models.py:13 .\oauth\models.py:23
#: .\oauth\models.py:53
msgid "creation time"
msgstr "creation time"
#: .\accounts\models.py:14 .\comments\models.py:14 .\oauth\models.py:24
#: .\oauth\models.py:54
msgid "last modify time"
msgstr "last modify time"
#: .\accounts\models.py:15
msgid "create source"
msgstr "create source"
#: .\accounts\models.py:33 .\djangoblog\logentryadmin.py:113
msgid "user"
msgstr "user"
#: .\accounts\tests.py:216 .\accounts\utils.py:38
#, fuzzy
#| msgid "get verification code"
msgid "Verification code error"
msgstr "get verification code"
#: .\accounts\utils.py:13
msgid "Verify Email"
msgstr "Verify Email"
#: .\accounts\utils.py:21
#, python-brace-format
msgid ""
"You are resetting the password, the verification code is{code}, valid "
"within 5 minutes, please keep it properly"
msgstr ""
"You are resetting the password, the verification code is{code}, valid "
"within 5 minutes, please keep it properly"
#: .\blog\admin.py:13 .\blog\models.py:92 .\comments\models.py:17
#: .\oauth\models.py:12 .\templates\blog\tags\article_meta_info.html:33
msgid "author"
msgstr "author"
#: .\blog\admin.py:53
msgid "Publish selected articles"
msgstr "Publish selected articles"
#: .\blog\admin.py:54
msgid "Draft selected articles"
msgstr "Draft selected articles"
#: .\blog\admin.py:55
msgid "Close article comments"
msgstr "Close article comments"
#: .\blog\admin.py:56
msgid "Open article comments"
msgstr "Open article comments"
#: .\blog\admin.py:89 .\blog\models.py:101 .\blog\models.py:183
#: .\templates\blog\tags\article_meta_info.html:17
#: .\templates\blog\tags\sidebar.html:40
msgid "category"
msgstr "category"
#: .\blog\models.py:20 .\blog\models.py:179
msgid "index"
msgstr "index"
#: .\blog\models.py:21
msgid "list"
msgstr "list"
#: .\blog\models.py:22
msgid "post"
msgstr "post"
#: .\blog\models.py:23
msgid "all"
msgstr "all"
#: .\blog\models.py:24
msgid "slide"
msgstr "slide"
#: .\blog\models.py:30 .\blog\models.py:267 .\blog\models.py:285
msgid "modify time"
msgstr "modify time"
#: .\blog\models.py:63
msgid "Draft"
msgstr "Draft"
#: .\blog\models.py:64
msgid "Published"
msgstr "Published"
#: .\blog\models.py:67
msgid "Open"
msgstr "Open"
#: .\blog\models.py:68
msgid "Close"
msgstr "Close"
#: .\blog\models.py:71 .\comments\admin.py:47
msgid "Article"
msgstr "Article"
#: .\blog\models.py:72
msgid "Page"
msgstr "Page"
#: .\blog\models.py:74 .\blog\models.py:280
msgid "title"
msgstr "title"
#: .\blog\models.py:75
msgid "body"
msgstr "body"
#: .\blog\models.py:77
msgid "publish time"
msgstr "publish time"
#: .\blog\models.py:79
msgid "status"
msgstr "status"
#: .\blog\models.py:84
msgid "comment status"
msgstr "comment status"
#: .\blog\models.py:88 .\oauth\models.py:43
msgid "type"
msgstr "type"
#: .\blog\models.py:89
msgid "views"
msgstr "views"
#: .\blog\models.py:97 .\blog\models.py:258 .\blog\models.py:282
msgid "order"
msgstr "order"
#: .\blog\models.py:98
msgid "show toc"
msgstr "show toc"
#: .\blog\models.py:105 .\blog\models.py:249
#: .\templates\blog\tags\article_meta_info.html:22
msgid "tag"
msgstr "tag"
#: .\blog\models.py:115 .\comments\models.py:21
msgid "article"
msgstr "article"
#: .\blog\models.py:171
msgid "category name"
msgstr "category name"
#: .\blog\models.py:174
msgid "parent category"
msgstr "parent category"
#: .\blog\models.py:234
msgid "tag name"
msgstr "tag name"
#: .\blog\models.py:256
msgid "link name"
msgstr "link name"
#: .\blog\models.py:257 .\blog\models.py:271
msgid "link"
msgstr "link"
#: .\blog\models.py:260
msgid "is show"
msgstr "is show"
#: .\blog\models.py:262
msgid "show type"
msgstr "show type"
#: .\blog\models.py:281
msgid "content"
msgstr "content"
#: .\blog\models.py:283 .\oauth\models.py:52
msgid "is enable"
msgstr "is enable"
#: .\blog\models.py:289
msgid "sidebar"
msgstr "sidebar"
#: .\blog\models.py:299
msgid "site name"
msgstr "site name"
#: .\blog\models.py:305
msgid "site description"
msgstr ""
#: .\blog\models.py:311
msgid "site seo description"
msgstr ""
#: .\blog\models.py:313
msgid "site keywords"
msgstr ""
#: .\blog\models.py:318
msgid "article sub length"
msgstr ""
#: .\blog\models.py:319
msgid "sidebar article count"
msgstr ""
#: .\blog\models.py:320
msgid "sidebar comment count"
msgstr ""
#: .\blog\models.py:321
msgid "article comment count"
msgstr ""
#: .\blog\models.py:322
msgid "show adsense"
msgstr ""
#: .\blog\models.py:324
msgid "adsense code"
msgstr ""
#: .\blog\models.py:325
msgid "open site comment"
msgstr ""
#: .\blog\models.py:360
msgid "只能有一个配置"
msgstr ""
#: .\blog\views.py:349
msgid ""
"Sorry, the page you requested is not found, please click the home page to "
"see other?"
msgstr ""
#: .\blog\views.py:357
msgid "Sorry, the server is busy, please click the home page to see other?"
msgstr ""
#: .\blog\views.py:370
msgid "Sorry, you do not have permission to access this page?"
msgstr ""
#: .\comments\admin.py:15
msgid "Disable comments"
msgstr ""
#: .\comments\admin.py:16
msgid "Enable comments"
msgstr ""
#: .\comments\admin.py:46
msgid "User"
msgstr ""
#: .\comments\models.py:25
msgid "parent comment"
msgstr ""
#: .\comments\models.py:29
msgid "enable"
msgstr ""
#: .\comments\models.py:34 .\templates\blog\tags\article_info.html:30
msgid "comment"
msgstr ""
#: .\comments\utils.py:13
msgid "Thanks for your comment"
msgstr ""
#: .\comments\utils.py:15
#, python-brace-format
msgid ""
"\n"
" <p>Thank you very much for your comments on this site</"
"p>\n"
" You can visit\n"
" <a href=\"{article_url}\" rel=\"bookmark\">{comment."
"article.title}</a>\n"
" to review your comments,\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this "
"link to your browser.\n"
" {article_url}\n"
" "
msgstr ""
#: .\comments\utils.py:29
#, python-brace-format
msgid ""
"\n"
" Your comment on <a href=\"{article_url}\" rel=\"bookmark"
"\">{comment.article.title}</a><br/> {comment.parent_comment.body} <br/> has "
"received a reply. go check it out\n"
" <br/>\n"
" If the link above cannot be opened, please copy this "
"link to your browser.\n"
" {article_url}\n"
" "
msgstr ""
#: .\djangoblog\logentryadmin.py:11
msgctxt "logentry_admin:action_type"
msgid "Addition"
msgstr ""
#: .\djangoblog\logentryadmin.py:12
msgctxt "logentry_admin:action_type"
msgid "Deletion"
msgstr ""
#: .\djangoblog\logentryadmin.py:13
msgctxt "logentry_admin:action_type"
msgid "Change"
msgstr ""
#: .\djangoblog\logentryadmin.py:25
msgid "Metadata"
msgstr ""
#: .\djangoblog\logentryadmin.py:33
msgid "Details"
msgstr ""
#: .\djangoblog\logentryadmin.py:95
msgid "object"
msgstr ""
#: .\djangoblog\logentryadmin.py:128
msgid "action"
msgstr ""
#: .\djangoblog\logentryadmin.py:133
msgid "change message"
msgstr ""
#: .\djangoblog\settings.py:140
msgid "English"
msgstr ""
#: .\djangoblog\settings.py:141
msgid "Simplified Chinese"
msgstr ""
#: .\djangoblog\settings.py:142
msgid "Traditional Chinese"
msgstr ""
#: .\oauth\models.py:17
msgid "nickname"
msgstr ""
#: .\oauth\models.py:30
msgid "oauth user"
msgstr ""
#: .\oauth\models.py:37
msgid "weibo"
msgstr ""
#: .\oauth\models.py:38
msgid "google"
msgstr ""
#: .\oauth\models.py:48
msgid "callback url"
msgstr ""
#: .\oauth\models.py:59
msgid "already exists"
msgstr ""
#: .\oauth\views.py:154
msgid ""
"\n"
" <p>Congratulations, you have successfully bound your email address. You "
"can use {oauthuser.type} to directly log in to this website without a "
"password. You are welcome to continue to follow this site, the address is</"
"p>\n"
"\n"
" <a href=\"{'http://' + site}\" rel=\"bookmark\">{'http://' "
"+ site}</a>\n"
"\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this link "
"to your browser.\n"
" {site}\n"
" "
msgstr ""
#: .\oauth\views.py:165
msgid "Congratulations on your successful binding!"
msgstr ""
#: .\oauth\views.py:217
#, python-brace-format
msgid ""
"\n"
" <p>Please click the link below to bind your email</p>\n"
"\n"
" <a href=\"{url}\" rel=\"bookmark\">{url}</a>\n"
"\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this link "
"to your browser.\n"
" {url}\n"
" "
msgstr ""
#: .\oauth\views.py:227 .\oauth\views.py:239
msgid "Bind your email"
msgstr ""
#: .\oauth\views.py:241
msgid ""
"Congratulations, the binding is just one step away. Please log in to your "
"email to check the email to complete the binding. Thank you."
msgstr ""
#: .\oauth\views.py:243
msgid "Binding successful"
msgstr ""
#: .\oauth\views.py:245
#, python-brace-format
msgid ""
"Congratulations, you have successfully bound your email address. You can use "
"{oauthuser.type} to directly log in to this website without a password. You "
"are welcome to continue to follow this site."
msgstr ""
#: .\templates\account\forget_password.html:7
msgid "forget the password"
msgstr "forget the password"
#: .\templates\account\forget_password.html:18
msgid "get verification code"
msgstr "get verification code"
#: .\templates\account\forget_password.html:19
msgid "submit"
msgstr "submit"
#: .\templates\account\result.html:18 .\templates\blog\tags\sidebar.html:126
msgid "login"
msgstr ""
#: .\templates\account\result.html:22
msgid "back to the homepage"
msgstr ""
#: .\templates\blog\article_archives.html:7
#: .\templates\blog\article_archives.html:24
msgid "article archive"
msgstr ""
#: .\templates\blog\article_archives.html:32
msgid "year"
msgstr ""
#: .\templates\blog\article_archives.html:36
msgid "month"
msgstr ""
#: .\templates\blog\tags\article_info.html:12
msgid "pin to top"
msgstr ""
#: .\templates\blog\tags\article_info.html:28
msgid "comments"
msgstr ""
#: .\templates\blog\tags\article_info.html:58
msgid "toc"
msgstr ""
#: .\templates\blog\tags\article_meta_info.html:7
#, fuzzy
#| msgid "Published"
msgid "Published on"
msgstr "Published"
#: .\templates\blog\tags\article_meta_info.html:36
#, python-format
msgid ""
"\n"
" title=\"View all articles published by "
"%(article.author.username)s\"\n"
" "
msgstr ""
"\n"
" title=\"View all articles published by "
"%(article.author.username)s\"\n"
" "
#: .\templates\blog\tags\article_meta_info.html:50
msgid "edit"
msgstr "edit"
#: .\templates\blog\tags\article_pagination.html:4
msgid "article navigation"
msgstr ""
#: .\templates\blog\tags\article_pagination.html:9
msgid "earlier articles"
msgstr ""
#: .\templates\blog\tags\article_pagination.html:12
msgid "newer articles"
msgstr ""
#: .\templates\blog\tags\article_tag_list.html:5
msgid "tags"
msgstr "tags"
#: .\templates\blog\tags\sidebar.html:7
msgid "search"
msgstr ""
#: .\templates\blog\tags\sidebar.html:50
msgid "recent comments"
msgstr ""
#: .\templates\blog\tags\sidebar.html:57
msgid "published in"
msgstr ""
#: .\templates\blog\tags\sidebar.html:65
msgid "recent articles"
msgstr ""
#: .\templates\blog\tags\sidebar.html:77
msgid "bookmark"
msgstr ""
#: .\templates\blog\tags\sidebar.html:96
msgid "Tag Cloud"
msgstr ""
#: .\templates\blog\tags\sidebar.html:107
msgid "Welcome to star or fork the source code of this site"
msgstr ""
#: .\templates\blog\tags\sidebar.html:118
msgid "Function"
msgstr ""
#: .\templates\blog\tags\sidebar.html:120
msgid "management site"
msgstr ""
#: .\templates\blog\tags\sidebar.html:122
msgid "logout"
msgstr ""
#: .\templates\blog\tags\sidebar.html:129
msgid "Track record"
msgstr ""
#: .\templates\blog\tags\sidebar.html:135
msgid "Click me to return to the top"
msgstr ""
#~ msgid "This entry was published on"
#~ msgstr "This entry was published on"
#~ msgid "belongs"
#~ msgstr "belongs"
#~ msgid "been"
#~ msgstr "been"

View File

@@ -0,0 +1,665 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-07 23:54+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: .\accounts\admin.py:13
msgid "password"
msgstr "密码"
#: .\accounts\admin.py:14
msgid "Enter password again"
msgstr "再次输入密码"
#: .\accounts\admin.py:25 .\accounts\forms.py:89
msgid "passwords do not match"
msgstr "密码不匹配"
#: .\accounts\admin.py:40
msgid "Password"
msgstr "密码"
#: .\accounts\admin.py:42
msgid ""
"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>."
msgstr ""
"未存储原始密码,因此无法看到此用户的密码,但您可以使用”更改密码<a href="
"\"{}\">此表单</a>。"
#: .\accounts\forms.py:36
msgid "email already exists"
msgstr "邮箱已存在"
#: .\accounts\forms.py:46 .\accounts\forms.py:50
#, fuzzy
#| msgid "forget the password"
msgid "New password"
msgstr "新密码"
#: .\accounts\forms.py:60
#, fuzzy
#| msgid "forget the password"
msgid "Confirm password"
msgstr "确认密码"
#: .\accounts\forms.py:70 .\accounts\forms.py:116
msgid "Email"
msgstr "邮箱"
#: .\accounts\forms.py:76 .\accounts\forms.py:80
msgid "Code"
msgstr "验证码"
#: .\accounts\forms.py:100 .\accounts\tests.py:194
msgid "email does not exist"
msgstr "邮箱不存在"
#: .\accounts\models.py:12
msgid "nick name"
msgstr "昵称"
#: .\accounts\models.py:13 .\blog\models.py:29 .\blog\models.py:266
#: .\blog\models.py:284 .\comments\models.py:13 .\oauth\models.py:23
#: .\oauth\models.py:53
msgid "creation time"
msgstr "创建时间"
#: .\accounts\models.py:14 .\comments\models.py:14 .\oauth\models.py:24
#: .\oauth\models.py:54
msgid "last modify time"
msgstr "最后修改时间"
#: .\accounts\models.py:15
msgid "create source"
msgstr "来源"
#: .\accounts\models.py:33 .\djangoblog\logentryadmin.py:113
msgid "user"
msgstr "用户"
#: .\accounts\tests.py:216 .\accounts\utils.py:38
#, fuzzy
#| msgid "get verification code"
msgid "Verification code error"
msgstr "验证码错误"
#: .\accounts\utils.py:13
msgid "Verify Email"
msgstr "验证邮箱"
#: .\accounts\utils.py:21
#, python-brace-format
msgid ""
"You are resetting the password, the verification code is{code}, valid "
"within 5 minutes, please keep it properly"
msgstr "您正在重置密码,验证码为:{code}5分钟内有效 请妥善保管"
#: .\blog\admin.py:13 .\blog\models.py:92 .\comments\models.py:17
#: .\oauth\models.py:12 .\templates\blog\tags\article_meta_info.html:33
msgid "author"
msgstr "作者"
#: .\blog\admin.py:53
msgid "Publish selected articles"
msgstr "发布选中的文章"
#: .\blog\admin.py:54
msgid "Draft selected articles"
msgstr "选中文章设为草稿"
#: .\blog\admin.py:55
msgid "Close article comments"
msgstr "关闭文章评论"
#: .\blog\admin.py:56
msgid "Open article comments"
msgstr "打开文章评论"
#: .\blog\admin.py:89 .\blog\models.py:101 .\blog\models.py:183
#: .\templates\blog\tags\article_meta_info.html:17
#: .\templates\blog\tags\sidebar.html:40
msgid "category"
msgstr "分类目录"
#: .\blog\models.py:20 .\blog\models.py:179
msgid "index"
msgstr "首页"
#: .\blog\models.py:21
msgid "list"
msgstr "列表"
#: .\blog\models.py:22
msgid "post"
msgstr "文章"
#: .\blog\models.py:23
msgid "all"
msgstr "所有"
#: .\blog\models.py:24
msgid "slide"
msgstr "侧边栏"
#: .\blog\models.py:30 .\blog\models.py:267 .\blog\models.py:285
msgid "modify time"
msgstr "修改时间"
#: .\blog\models.py:63
msgid "Draft"
msgstr "草稿"
#: .\blog\models.py:64
msgid "Published"
msgstr "发布"
#: .\blog\models.py:67
msgid "Open"
msgstr "打开"
#: .\blog\models.py:68
msgid "Close"
msgstr "关闭"
#: .\blog\models.py:71 .\comments\admin.py:47
msgid "Article"
msgstr "文章"
#: .\blog\models.py:72
msgid "Page"
msgstr "页面"
#: .\blog\models.py:74 .\blog\models.py:280
msgid "title"
msgstr "标题"
#: .\blog\models.py:75
msgid "body"
msgstr "内容"
#: .\blog\models.py:77
msgid "publish time"
msgstr "发布时间"
#: .\blog\models.py:79
msgid "status"
msgstr "状态"
#: .\blog\models.py:84
msgid "comment status"
msgstr "评论状态"
#: .\blog\models.py:88 .\oauth\models.py:43
msgid "type"
msgstr "类型"
#: .\blog\models.py:89
msgid "views"
msgstr "阅读量"
#: .\blog\models.py:97 .\blog\models.py:258 .\blog\models.py:282
msgid "order"
msgstr "排序"
#: .\blog\models.py:98
msgid "show toc"
msgstr "显示目录"
#: .\blog\models.py:105 .\blog\models.py:249
#: .\templates\blog\tags\article_meta_info.html:22
msgid "tag"
msgstr "标签"
#: .\blog\models.py:115 .\comments\models.py:21
msgid "article"
msgstr "文章"
#: .\blog\models.py:171
msgid "category name"
msgstr "分类名"
#: .\blog\models.py:174
msgid "parent category"
msgstr "上级分类"
#: .\blog\models.py:234
msgid "tag name"
msgstr "标签名"
#: .\blog\models.py:256
msgid "link name"
msgstr "链接名"
#: .\blog\models.py:257 .\blog\models.py:271
msgid "link"
msgstr "链接"
#: .\blog\models.py:260
msgid "is show"
msgstr "是否显示"
#: .\blog\models.py:262
msgid "show type"
msgstr "显示类型"
#: .\blog\models.py:281
msgid "content"
msgstr "内容"
#: .\blog\models.py:283 .\oauth\models.py:52
msgid "is enable"
msgstr "是否启用"
#: .\blog\models.py:289
msgid "sidebar"
msgstr "侧边栏"
#: .\blog\models.py:299
msgid "site name"
msgstr "站点名称"
#: .\blog\models.py:305
msgid "site description"
msgstr "站点描述"
#: .\blog\models.py:311
msgid "site seo description"
msgstr "站点SEO描述"
#: .\blog\models.py:313
msgid "site keywords"
msgstr "关键字"
#: .\blog\models.py:318
msgid "article sub length"
msgstr "文章摘要长度"
#: .\blog\models.py:319
msgid "sidebar article count"
msgstr "侧边栏文章数目"
#: .\blog\models.py:320
msgid "sidebar comment count"
msgstr "侧边栏评论数目"
#: .\blog\models.py:321
msgid "article comment count"
msgstr "文章页面默认显示评论数目"
#: .\blog\models.py:322
msgid "show adsense"
msgstr "是否显示广告"
#: .\blog\models.py:324
msgid "adsense code"
msgstr "广告内容"
#: .\blog\models.py:325
msgid "open site comment"
msgstr "公共头部"
#: .\blog\models.py:360
msgid "只能有一个配置"
msgstr ""
#: .\blog\views.py:349
msgid ""
"Sorry, the page you requested is not found, please click the home page to "
"see other?"
msgstr ""
#: .\blog\views.py:357
msgid "Sorry, the server is busy, please click the home page to see other?"
msgstr ""
#: .\blog\views.py:370
msgid "Sorry, you do not have permission to access this page?"
msgstr ""
#: .\comments\admin.py:15
msgid "Disable comments"
msgstr ""
#: .\comments\admin.py:16
msgid "Enable comments"
msgstr ""
#: .\comments\admin.py:46
msgid "User"
msgstr ""
#: .\comments\models.py:25
msgid "parent comment"
msgstr ""
#: .\comments\models.py:29
msgid "enable"
msgstr ""
#: .\comments\models.py:34 .\templates\blog\tags\article_info.html:30
msgid "comment"
msgstr ""
#: .\comments\utils.py:13
msgid "Thanks for your comment"
msgstr ""
#: .\comments\utils.py:15
#, python-brace-format
msgid ""
"\n"
" <p>Thank you very much for your comments on this site</"
"p>\n"
" You can visit\n"
" <a href=\"{article_url}\" rel=\"bookmark\">{comment."
"article.title}</a>\n"
" to review your comments,\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this "
"link to your browser.\n"
" {article_url}\n"
" "
msgstr ""
#: .\comments\utils.py:29
#, python-brace-format
msgid ""
"\n"
" Your comment on <a href=\"{article_url}\" rel=\"bookmark"
"\">{comment.article.title}</a><br/> {comment.parent_comment.body} <br/> has "
"received a reply. go check it out\n"
" <br/>\n"
" If the link above cannot be opened, please copy this "
"link to your browser.\n"
" {article_url}\n"
" "
msgstr ""
#: .\djangoblog\logentryadmin.py:11
msgctxt "logentry_admin:action_type"
msgid "Addition"
msgstr ""
#: .\djangoblog\logentryadmin.py:12
msgctxt "logentry_admin:action_type"
msgid "Deletion"
msgstr ""
#: .\djangoblog\logentryadmin.py:13
msgctxt "logentry_admin:action_type"
msgid "Change"
msgstr ""
#: .\djangoblog\logentryadmin.py:25
msgid "Metadata"
msgstr ""
#: .\djangoblog\logentryadmin.py:33
msgid "Details"
msgstr ""
#: .\djangoblog\logentryadmin.py:95
msgid "object"
msgstr ""
#: .\djangoblog\logentryadmin.py:128
msgid "action"
msgstr ""
#: .\djangoblog\logentryadmin.py:133
msgid "change message"
msgstr ""
#: .\djangoblog\settings.py:140
msgid "English"
msgstr ""
#: .\djangoblog\settings.py:141
msgid "Simplified Chinese"
msgstr ""
#: .\djangoblog\settings.py:142
msgid "Traditional Chinese"
msgstr ""
#: .\oauth\models.py:17
msgid "nickname"
msgstr ""
#: .\oauth\models.py:30
msgid "oauth user"
msgstr ""
#: .\oauth\models.py:37
msgid "weibo"
msgstr ""
#: .\oauth\models.py:38
msgid "google"
msgstr ""
#: .\oauth\models.py:48
msgid "callback url"
msgstr ""
#: .\oauth\models.py:59
msgid "already exists"
msgstr ""
#: .\oauth\views.py:154
msgid ""
"\n"
" <p>Congratulations, you have successfully bound your email address. You "
"can use {oauthuser.type} to directly log in to this website without a "
"password. You are welcome to continue to follow this site, the address is</"
"p>\n"
"\n"
" <a href=\"{'http://' + site}\" rel=\"bookmark\">{'http://' "
"+ site}</a>\n"
"\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this link "
"to your browser.\n"
" {site}\n"
" "
msgstr ""
#: .\oauth\views.py:165
msgid "Congratulations on your successful binding!"
msgstr ""
#: .\oauth\views.py:217
#, python-brace-format
msgid ""
"\n"
" <p>Please click the link below to bind your email</p>\n"
"\n"
" <a href=\"{url}\" rel=\"bookmark\">{url}</a>\n"
"\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this link "
"to your browser.\n"
" {url}\n"
" "
msgstr ""
#: .\oauth\views.py:227 .\oauth\views.py:239
msgid "Bind your email"
msgstr ""
#: .\oauth\views.py:241
msgid ""
"Congratulations, the binding is just one step away. Please log in to your "
"email to check the email to complete the binding. Thank you."
msgstr ""
#: .\oauth\views.py:243
msgid "Binding successful"
msgstr ""
#: .\oauth\views.py:245
#, python-brace-format
msgid ""
"Congratulations, you have successfully bound your email address. You can use "
"{oauthuser.type} to directly log in to this website without a password. You "
"are welcome to continue to follow this site."
msgstr ""
#: .\templates\account\forget_password.html:7
msgid "forget the password"
msgstr "忘记密码"
#: .\templates\account\forget_password.html:18
msgid "get verification code"
msgstr "获取验证码"
#: .\templates\account\forget_password.html:19
msgid "submit"
msgstr "提交"
#: .\templates\account\result.html:18 .\templates\blog\tags\sidebar.html:126
msgid "login"
msgstr ""
#: .\templates\account\result.html:22
msgid "back to the homepage"
msgstr ""
#: .\templates\blog\article_archives.html:7
#: .\templates\blog\article_archives.html:24
msgid "article archive"
msgstr ""
#: .\templates\blog\article_archives.html:32
msgid "year"
msgstr ""
#: .\templates\blog\article_archives.html:36
msgid "month"
msgstr ""
#: .\templates\blog\tags\article_info.html:12
msgid "pin to top"
msgstr ""
#: .\templates\blog\tags\article_info.html:28
msgid "comments"
msgstr ""
#: .\templates\blog\tags\article_info.html:58
msgid "toc"
msgstr ""
#: .\templates\blog\tags\article_meta_info.html:7
#, fuzzy
#| msgid "Published"
msgid "Published on"
msgstr "发表于"
#: .\templates\blog\tags\article_meta_info.html:36
#, python-format
msgid ""
"\n"
" title=\"View all articles published by "
"%(article.author.username)s\"\n"
" "
msgstr ""
"\n"
" title=\"查看所有由 "
"%(article.author.username)s\"发布的文章\n"
" "
#: .\templates\blog\tags\article_meta_info.html:50
msgid "edit"
msgstr "编辑"
#: .\templates\blog\tags\article_pagination.html:4
msgid "article navigation"
msgstr ""
#: .\templates\blog\tags\article_pagination.html:9
msgid "earlier articles"
msgstr ""
#: .\templates\blog\tags\article_pagination.html:12
msgid "newer articles"
msgstr ""
#: .\templates\blog\tags\article_tag_list.html:5
msgid "tags"
msgstr "标签"
#: .\templates\blog\tags\sidebar.html:7
msgid "search"
msgstr ""
#: .\templates\blog\tags\sidebar.html:50
msgid "recent comments"
msgstr ""
#: .\templates\blog\tags\sidebar.html:57
msgid "published in"
msgstr ""
#: .\templates\blog\tags\sidebar.html:65
msgid "recent articles"
msgstr ""
#: .\templates\blog\tags\sidebar.html:77
msgid "bookmark"
msgstr ""
#: .\templates\blog\tags\sidebar.html:96
msgid "Tag Cloud"
msgstr ""
#: .\templates\blog\tags\sidebar.html:107
msgid "Welcome to star or fork the source code of this site"
msgstr ""
#: .\templates\blog\tags\sidebar.html:118
msgid "Function"
msgstr ""
#: .\templates\blog\tags\sidebar.html:120
msgid "management site"
msgstr ""
#: .\templates\blog\tags\sidebar.html:122
msgid "logout"
msgstr ""
#: .\templates\blog\tags\sidebar.html:129
msgid "Track record"
msgstr ""
#: .\templates\blog\tags\sidebar.html:135
msgid "Click me to return to the top"
msgstr ""
#~ msgid "This entry was published on"
#~ msgstr "这篇文章发布在 "
#~ msgid "belongs"
#~ msgstr "属于"
#~ msgid "been"
#~ msgstr "贴了"

View File

@@ -0,0 +1,643 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-07 23:54+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: .\accounts\admin.py:13
msgid "password"
msgstr ""
#: .\accounts\admin.py:14
msgid "Enter password again"
msgstr ""
#: .\accounts\admin.py:25 .\accounts\forms.py:89
msgid "passwords do not match"
msgstr ""
#: .\accounts\admin.py:40
msgid "Password"
msgstr ""
#: .\accounts\admin.py:42
msgid ""
"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>."
msgstr ""
#: .\accounts\forms.py:36
msgid "email already exists"
msgstr ""
#: .\accounts\forms.py:46 .\accounts\forms.py:50
msgid "New password"
msgstr ""
#: .\accounts\forms.py:60
msgid "Confirm password"
msgstr ""
#: .\accounts\forms.py:70 .\accounts\forms.py:116
msgid "Email"
msgstr ""
#: .\accounts\forms.py:76 .\accounts\forms.py:80
msgid "Code"
msgstr ""
#: .\accounts\forms.py:100 .\accounts\tests.py:194
msgid "email does not exist"
msgstr ""
#: .\accounts\models.py:12
msgid "nick name"
msgstr ""
#: .\accounts\models.py:13 .\blog\models.py:29 .\blog\models.py:266
#: .\blog\models.py:284 .\comments\models.py:13 .\oauth\models.py:23
#: .\oauth\models.py:53
msgid "creation time"
msgstr ""
#: .\accounts\models.py:14 .\comments\models.py:14 .\oauth\models.py:24
#: .\oauth\models.py:54
msgid "last modify time"
msgstr ""
#: .\accounts\models.py:15
msgid "create source"
msgstr ""
#: .\accounts\models.py:33 .\djangoblog\logentryadmin.py:113
msgid "user"
msgstr ""
#: .\accounts\tests.py:216 .\accounts\utils.py:38
msgid "Verification code error"
msgstr ""
#: .\accounts\utils.py:13
msgid "Verify Email"
msgstr ""
#: .\accounts\utils.py:21
#, python-brace-format
msgid ""
"You are resetting the password, the verification code is{code}, valid "
"within 5 minutes, please keep it properly"
msgstr ""
#: .\blog\admin.py:13 .\blog\models.py:92 .\comments\models.py:17
#: .\oauth\models.py:12 .\templates\blog\tags\article_meta_info.html:33
msgid "author"
msgstr ""
#: .\blog\admin.py:53
msgid "Publish selected articles"
msgstr ""
#: .\blog\admin.py:54
msgid "Draft selected articles"
msgstr ""
#: .\blog\admin.py:55
msgid "Close article comments"
msgstr ""
#: .\blog\admin.py:56
msgid "Open article comments"
msgstr ""
#: .\blog\admin.py:89 .\blog\models.py:101 .\blog\models.py:183
#: .\templates\blog\tags\article_meta_info.html:17
#: .\templates\blog\tags\sidebar.html:40
msgid "category"
msgstr ""
#: .\blog\models.py:20 .\blog\models.py:179
msgid "index"
msgstr ""
#: .\blog\models.py:21
msgid "list"
msgstr ""
#: .\blog\models.py:22
msgid "post"
msgstr ""
#: .\blog\models.py:23
msgid "all"
msgstr ""
#: .\blog\models.py:24
msgid "slide"
msgstr ""
#: .\blog\models.py:30 .\blog\models.py:267 .\blog\models.py:285
msgid "modify time"
msgstr ""
#: .\blog\models.py:63
msgid "Draft"
msgstr ""
#: .\blog\models.py:64
msgid "Published"
msgstr ""
#: .\blog\models.py:67
msgid "Open"
msgstr ""
#: .\blog\models.py:68
msgid "Close"
msgstr ""
#: .\blog\models.py:71 .\comments\admin.py:47
msgid "Article"
msgstr ""
#: .\blog\models.py:72
msgid "Page"
msgstr ""
#: .\blog\models.py:74 .\blog\models.py:280
msgid "title"
msgstr ""
#: .\blog\models.py:75
msgid "body"
msgstr ""
#: .\blog\models.py:77
msgid "publish time"
msgstr ""
#: .\blog\models.py:79
msgid "status"
msgstr ""
#: .\blog\models.py:84
msgid "comment status"
msgstr ""
#: .\blog\models.py:88 .\oauth\models.py:43
msgid "type"
msgstr ""
#: .\blog\models.py:89
msgid "views"
msgstr ""
#: .\blog\models.py:97 .\blog\models.py:258 .\blog\models.py:282
msgid "order"
msgstr ""
#: .\blog\models.py:98
msgid "show toc"
msgstr ""
#: .\blog\models.py:105 .\blog\models.py:249
#: .\templates\blog\tags\article_meta_info.html:22
msgid "tag"
msgstr ""
#: .\blog\models.py:115 .\comments\models.py:21
msgid "article"
msgstr ""
#: .\blog\models.py:171
msgid "category name"
msgstr ""
#: .\blog\models.py:174
msgid "parent category"
msgstr ""
#: .\blog\models.py:234
msgid "tag name"
msgstr ""
#: .\blog\models.py:256
msgid "link name"
msgstr ""
#: .\blog\models.py:257 .\blog\models.py:271
msgid "link"
msgstr ""
#: .\blog\models.py:260
msgid "is show"
msgstr ""
#: .\blog\models.py:262
msgid "show type"
msgstr ""
#: .\blog\models.py:281
msgid "content"
msgstr ""
#: .\blog\models.py:283 .\oauth\models.py:52
msgid "is enable"
msgstr ""
#: .\blog\models.py:289
msgid "sidebar"
msgstr ""
#: .\blog\models.py:299
msgid "site name"
msgstr ""
#: .\blog\models.py:305
msgid "site description"
msgstr ""
#: .\blog\models.py:311
msgid "site seo description"
msgstr ""
#: .\blog\models.py:313
msgid "site keywords"
msgstr ""
#: .\blog\models.py:318
msgid "article sub length"
msgstr ""
#: .\blog\models.py:319
msgid "sidebar article count"
msgstr ""
#: .\blog\models.py:320
msgid "sidebar comment count"
msgstr ""
#: .\blog\models.py:321
msgid "article comment count"
msgstr ""
#: .\blog\models.py:322
msgid "show adsense"
msgstr ""
#: .\blog\models.py:324
msgid "adsense code"
msgstr ""
#: .\blog\models.py:325
msgid "open site comment"
msgstr ""
#: .\blog\models.py:360
msgid "只能有一个配置"
msgstr ""
#: .\blog\views.py:349
msgid ""
"Sorry, the page you requested is not found, please click the home page to "
"see other?"
msgstr ""
#: .\blog\views.py:357
msgid "Sorry, the server is busy, please click the home page to see other?"
msgstr ""
#: .\blog\views.py:370
msgid "Sorry, you do not have permission to access this page?"
msgstr ""
#: .\comments\admin.py:15
msgid "Disable comments"
msgstr ""
#: .\comments\admin.py:16
msgid "Enable comments"
msgstr ""
#: .\comments\admin.py:46
msgid "User"
msgstr ""
#: .\comments\models.py:25
msgid "parent comment"
msgstr ""
#: .\comments\models.py:29
msgid "enable"
msgstr ""
#: .\comments\models.py:34 .\templates\blog\tags\article_info.html:30
msgid "comment"
msgstr ""
#: .\comments\utils.py:13
msgid "Thanks for your comment"
msgstr ""
#: .\comments\utils.py:15
#, python-brace-format
msgid ""
"\n"
" <p>Thank you very much for your comments on this site</"
"p>\n"
" You can visit\n"
" <a href=\"{article_url}\" rel=\"bookmark\">{comment."
"article.title}</a>\n"
" to review your comments,\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this "
"link to your browser.\n"
" {article_url}\n"
" "
msgstr ""
#: .\comments\utils.py:29
#, python-brace-format
msgid ""
"\n"
" Your comment on <a href=\"{article_url}\" rel=\"bookmark"
"\">{comment.article.title}</a><br/> {comment.parent_comment.body} <br/> has "
"received a reply. go check it out\n"
" <br/>\n"
" If the link above cannot be opened, please copy this "
"link to your browser.\n"
" {article_url}\n"
" "
msgstr ""
#: .\djangoblog\logentryadmin.py:11
msgctxt "logentry_admin:action_type"
msgid "Addition"
msgstr ""
#: .\djangoblog\logentryadmin.py:12
msgctxt "logentry_admin:action_type"
msgid "Deletion"
msgstr ""
#: .\djangoblog\logentryadmin.py:13
msgctxt "logentry_admin:action_type"
msgid "Change"
msgstr ""
#: .\djangoblog\logentryadmin.py:25
msgid "Metadata"
msgstr ""
#: .\djangoblog\logentryadmin.py:33
msgid "Details"
msgstr ""
#: .\djangoblog\logentryadmin.py:95
msgid "object"
msgstr ""
#: .\djangoblog\logentryadmin.py:128
msgid "action"
msgstr ""
#: .\djangoblog\logentryadmin.py:133
msgid "change message"
msgstr ""
#: .\djangoblog\settings.py:140
msgid "English"
msgstr ""
#: .\djangoblog\settings.py:141
msgid "Simplified Chinese"
msgstr ""
#: .\djangoblog\settings.py:142
msgid "Traditional Chinese"
msgstr ""
#: .\oauth\models.py:17
msgid "nickname"
msgstr ""
#: .\oauth\models.py:30
msgid "oauth user"
msgstr ""
#: .\oauth\models.py:37
msgid "weibo"
msgstr ""
#: .\oauth\models.py:38
msgid "google"
msgstr ""
#: .\oauth\models.py:48
msgid "callback url"
msgstr ""
#: .\oauth\models.py:59
msgid "already exists"
msgstr ""
#: .\oauth\views.py:154
msgid ""
"\n"
" <p>Congratulations, you have successfully bound your email address. You "
"can use {oauthuser.type} to directly log in to this website without a "
"password. You are welcome to continue to follow this site, the address is</"
"p>\n"
"\n"
" <a href=\"{'http://' + site}\" rel=\"bookmark\">{'http://' "
"+ site}</a>\n"
"\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this link "
"to your browser.\n"
" {site}\n"
" "
msgstr ""
#: .\oauth\views.py:165
msgid "Congratulations on your successful binding!"
msgstr ""
#: .\oauth\views.py:217
#, python-brace-format
msgid ""
"\n"
" <p>Please click the link below to bind your email</p>\n"
"\n"
" <a href=\"{url}\" rel=\"bookmark\">{url}</a>\n"
"\n"
" Thank you again!\n"
" <br />\n"
" If the link above cannot be opened, please copy this link "
"to your browser.\n"
" {url}\n"
" "
msgstr ""
#: .\oauth\views.py:227 .\oauth\views.py:239
msgid "Bind your email"
msgstr ""
#: .\oauth\views.py:241
msgid ""
"Congratulations, the binding is just one step away. Please log in to your "
"email to check the email to complete the binding. Thank you."
msgstr ""
#: .\oauth\views.py:243
msgid "Binding successful"
msgstr ""
#: .\oauth\views.py:245
#, python-brace-format
msgid ""
"Congratulations, you have successfully bound your email address. You can use "
"{oauthuser.type} to directly log in to this website without a password. You "
"are welcome to continue to follow this site."
msgstr ""
#: .\templates\account\forget_password.html:7
msgid "forget the password"
msgstr ""
#: .\templates\account\forget_password.html:18
msgid "get verification code"
msgstr ""
#: .\templates\account\forget_password.html:19
msgid "submit"
msgstr ""
#: .\templates\account\result.html:18 .\templates\blog\tags\sidebar.html:126
msgid "login"
msgstr ""
#: .\templates\account\result.html:22
msgid "back to the homepage"
msgstr ""
#: .\templates\blog\article_archives.html:7
#: .\templates\blog\article_archives.html:24
msgid "article archive"
msgstr ""
#: .\templates\blog\article_archives.html:32
msgid "year"
msgstr ""
#: .\templates\blog\article_archives.html:36
msgid "month"
msgstr ""
#: .\templates\blog\tags\article_info.html:12
msgid "pin to top"
msgstr ""
#: .\templates\blog\tags\article_info.html:28
msgid "comments"
msgstr ""
#: .\templates\blog\tags\article_info.html:58
msgid "toc"
msgstr ""
#: .\templates\blog\tags\article_meta_info.html:7
msgid "Published on"
msgstr "发表于"
#: .\templates\blog\tags\article_meta_info.html:36
#, python-format
msgid ""
"\n"
" title=\"View all articles published by "
"%(article.author.username)s\"\n"
" "
msgstr ""
#: .\templates\blog\tags\article_meta_info.html:50
msgid "edit"
msgstr ""
#: .\templates\blog\tags\article_pagination.html:4
msgid "article navigation"
msgstr ""
#: .\templates\blog\tags\article_pagination.html:9
msgid "earlier articles"
msgstr ""
#: .\templates\blog\tags\article_pagination.html:12
msgid "newer articles"
msgstr ""
#: .\templates\blog\tags\article_tag_list.html:5
msgid "tags"
msgstr ""
#: .\templates\blog\tags\sidebar.html:7
msgid "search"
msgstr ""
#: .\templates\blog\tags\sidebar.html:50
msgid "recent comments"
msgstr ""
#: .\templates\blog\tags\sidebar.html:57
msgid "published in"
msgstr ""
#: .\templates\blog\tags\sidebar.html:65
msgid "recent articles"
msgstr ""
#: .\templates\blog\tags\sidebar.html:77
msgid "bookmark"
msgstr ""
#: .\templates\blog\tags\sidebar.html:96
msgid "Tag Cloud"
msgstr ""
#: .\templates\blog\tags\sidebar.html:107
msgid "Welcome to star or fork the source code of this site"
msgstr ""
#: .\templates\blog\tags\sidebar.html:118
msgid "Function"
msgstr ""
#: .\templates\blog\tags\sidebar.html:120
msgid "management site"
msgstr ""
#: .\templates\blog\tags\sidebar.html:122
msgid "logout"
msgstr ""
#: .\templates\blog\tags\sidebar.html:129
msgid "Track record"
msgstr ""
#: .\templates\blog\tags\sidebar.html:135
msgid "Click me to return to the top"
msgstr ""

View File

@@ -0,0 +1,86 @@
# Generated by Django 4.2.5 on 2023-09-06 13:13
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('oauth', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='oauthconfig',
options={'ordering': ['-creation_time'], 'verbose_name': 'oauth配置', 'verbose_name_plural': 'oauth配置'},
),
migrations.AlterModelOptions(
name='oauthuser',
options={'ordering': ['-creation_time'], 'verbose_name': 'oauth user', 'verbose_name_plural': 'oauth user'},
),
migrations.RemoveField(
model_name='oauthconfig',
name='created_time',
),
migrations.RemoveField(
model_name='oauthconfig',
name='last_mod_time',
),
migrations.RemoveField(
model_name='oauthuser',
name='created_time',
),
migrations.RemoveField(
model_name='oauthuser',
name='last_mod_time',
),
migrations.AddField(
model_name='oauthconfig',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='oauthconfig',
name='last_modify_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'),
),
migrations.AddField(
model_name='oauthuser',
name='creation_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='creation time'),
),
migrations.AddField(
model_name='oauthuser',
name='last_modify_time',
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='last modify time'),
),
migrations.AlterField(
model_name='oauthconfig',
name='callback_url',
field=models.CharField(default='', max_length=200, verbose_name='callback url'),
),
migrations.AlterField(
model_name='oauthconfig',
name='is_enable',
field=models.BooleanField(default=True, verbose_name='is enable'),
),
migrations.AlterField(
model_name='oauthconfig',
name='type',
field=models.CharField(choices=[('weibo', 'weibo'), ('google', 'google'), ('github', 'GitHub'), ('facebook', 'FaceBook'), ('qq', 'QQ')], default='a', max_length=10, verbose_name='type'),
),
migrations.AlterField(
model_name='oauthuser',
name='author',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='author'),
),
migrations.AlterField(
model_name='oauthuser',
name='nickname',
field=models.CharField(max_length=50, verbose_name='nickname'),
),
]

View File

@@ -9,54 +9,54 @@ from django.utils.translation import gettext_lazy as _
class OAuthUser(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name='用户',
verbose_name=_('author'),
blank=True,
null=True,
on_delete=models.CASCADE)
openid = models.CharField(max_length=50)
nickname = models.CharField(max_length=50, verbose_name='昵称')
nickname = models.CharField(max_length=50, verbose_name=_('nickname'))
token = models.CharField(max_length=150, null=True, blank=True)
picture = models.CharField(max_length=350, blank=True, null=True)
type = models.CharField(blank=False, null=False, max_length=50)
email = models.CharField(max_length=50, null=True, blank=True)
metadata = models.TextField(null=True, blank=True)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
creation_time = models.DateTimeField(_('creation time'), default=now)
last_modify_time = models.DateTimeField(_('last modify time'), default=now)
def __str__(self):
return self.nickname
class Meta:
verbose_name = 'oauth用户'
verbose_name = _('oauth user')
verbose_name_plural = verbose_name
ordering = ['-created_time']
ordering = ['-creation_time']
class OAuthConfig(models.Model):
TYPE = (
('weibo', '微博'),
('google', '谷歌'),
('weibo', _('weibo')),
('google', _('google')),
('github', 'GitHub'),
('facebook', 'FaceBook'),
('qq', 'QQ'),
)
type = models.CharField('类型', max_length=10, choices=TYPE, default='a')
type = models.CharField(_('type'), max_length=10, choices=TYPE, default='a')
appkey = models.CharField(max_length=200, verbose_name='AppKey')
appsecret = models.CharField(max_length=200, verbose_name='AppSecret')
callback_url = models.CharField(
max_length=200,
verbose_name='回调地址',
verbose_name=_('callback url'),
blank=False,
default='http://www.baidu.com')
default='')
is_enable = models.BooleanField(
'是否显示', default=True, blank=False, null=False)
created_time = models.DateTimeField('创建时间', default=now)
last_mod_time = models.DateTimeField('修改时间', default=now)
_('is enable'), default=True, blank=False, null=False)
creation_time = models.DateTimeField(_('creation time'), default=now)
last_modify_time = models.DateTimeField(_('last modify time'), default=now)
def clean(self):
if OAuthConfig.objects.filter(
type=self.type).exclude(id=self.id).count():
raise ValidationError(_(self.type + '已经存在'))
raise ValidationError(_(self.type + _('already exists')))
def __str__(self):
return self.type
@@ -64,4 +64,4 @@ class OAuthConfig(models.Model):
class Meta:
verbose_name = 'oauth配置'
verbose_name_plural = verbose_name
ordering = ['-created_time']
ordering = ['-creation_time']

View File

@@ -13,6 +13,7 @@ from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.views.generic import FormView
from djangoblog.blog_signals import oauth_user_login_signal
@@ -149,19 +150,19 @@ def emailconfirm(request, id, sign):
id=oauthuser.id)
login(request, author)
site = get_current_site().domain
content = '''
<p>恭喜您,您已经成功绑定您的邮箱,您可以使用{type}来直接免密码登录本网站.欢迎您继续关注本站,地址是</p>
site = 'http://' + get_current_site().domain
content = _(f'''
<p>Congratulations, you have successfully bound your email address. You can use {oauthuser.type} to directly log in to this website without a password. You are welcome to continue to follow this site, the address is</p>
<a href="{url}" rel="bookmark">{url}</a>
<a href="{'http://' + site}" rel="bookmark">{'http://' + site}</a>
再次感谢您!
<br />
如果上面链接无法打开,请将此链接复制至浏览器。
{url}
'''.format(type=oauthuser.type, url='http://' + site)
Thank you again!
<br />
If the link above cannot be opened, please copy this link to your browser.
{site}
''')
send_email(emailto=[oauthuser.email, ], title='恭喜您绑定成功!', content=content)
send_email(emailto=[oauthuser.email, ], title=_('Congratulations on your successful binding!'), content=content)
url = reverse('oauth:bindsuccess', kwargs={
'oauthid': id
})
@@ -213,17 +214,17 @@ class RequireEmailView(FormView):
})
url = "http://{site}{path}".format(site=site, path=path)
content = """
<p>请点击下面链接绑定您的邮箱</p>
content = _(f"""
<p>Please click the link below to bind your email</p>
<a href="{url}" rel="bookmark">{url}</a>
<a href="{url}" rel="bookmark">{url}</a>
再次感谢您!
<br />
如果上面链接无法打开,请将此链接复制至浏览器。
{url}
""".format(url=url)
send_email(emailto=[email, ], title='绑定您的电子邮箱', content=content)
Thank you again!
<br />
If the link above cannot be opened, please copy this link to your browser.
{url}
""")
send_email(emailto=[email, ], title=_('Bind your email'), content=content)
url = reverse('oauth:bindsuccess', kwargs={
'oauthid': oauthid
})
@@ -235,12 +236,13 @@ def bindsuccess(request, oauthid):
type = request.GET.get('type', None)
oauthuser = get_object_or_404(OAuthUser, pk=oauthid)
if type == 'email':
title = '绑定成功'
content = "恭喜您,还差一步就绑定成功了,请登录您的邮箱查看邮件完成绑定,谢谢。"
title = _('Bind your email')
content = _(
'Congratulations, the binding is just one step away. Please log in to your email to check the email to complete the binding. Thank you.')
else:
title = '绑定成功'
content = "恭喜您绑定成功,您以后可以使用{type}来直接免密码登录本站啦,感谢您对本站对关注。".format(
type=oauthuser.type)
title = _('Binding successful')
content = _(
f"Congratulations, you have successfully bound your email address. You can use {oauthuser.type} to directly log in to this website without a password. You are welcome to continue to follow this site.")
return render(request, 'oauth/bindsuccess.html', {
'title': title,
'content': content

View File

@@ -0,0 +1,22 @@
# Generated by Django 4.2.5 on 2023-09-06 13:19
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('owntracks', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='owntracklog',
options={'get_latest_by': 'creation_time', 'ordering': ['creation_time'], 'verbose_name': 'OwnTrackLogs', 'verbose_name_plural': 'OwnTrackLogs'},
),
migrations.RenameField(
model_name='owntracklog',
old_name='created_time',
new_name='creation_time',
),
]

View File

@@ -8,13 +8,13 @@ class OwnTrackLog(models.Model):
tid = models.CharField(max_length=100, null=False, verbose_name='用户')
lat = models.FloatField(verbose_name='纬度')
lon = models.FloatField(verbose_name='经度')
created_time = models.DateTimeField('创建时间', default=now)
creation_time = models.DateTimeField('创建时间', default=now)
def __str__(self):
return self.tid
class Meta:
ordering = ['created_time']
ordering = ['creation_time']
verbose_name = "OwnTrackLogs"
verbose_name_plural = verbose_name
get_latest_by = 'created_time'
get_latest_by = 'creation_time'

View File

@@ -59,7 +59,7 @@ def show_maps(request):
@login_required
def show_log_dates(request):
dates = OwnTrackLog.objects.values_list('created_time', flat=True)
dates = OwnTrackLog.objects.values_list('creation_time', flat=True)
results = list(sorted(set(map(lambda x: x.strftime('%Y-%m-%d'), dates))))
context = {
@@ -108,7 +108,7 @@ def get_datas(request):
querydate = django.utils.timezone.make_aware(querydate)
nextdate = querydate + datetime.timedelta(days=1)
models = OwnTrackLog.objects.filter(
created_time__range=(querydate, nextdate))
creation_time__range=(querydate, nextdate))
result = list()
if models and len(models):
for tid, item in groupby(

View File

@@ -7,12 +7,12 @@ class CommandsAdmin(admin.ModelAdmin):
class EmailSendLogAdmin(admin.ModelAdmin):
list_display = ('title', 'emailto', 'send_result', 'created_time')
list_display = ('title', 'emailto', 'send_result', 'creation_time')
readonly_fields = (
'title',
'emailto',
'send_result',
'created_time',
'creation_time',
'content')
def has_add_permission(self, request):

View File

@@ -0,0 +1,32 @@
# Generated by Django 4.2.5 on 2023-09-06 13:19
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('servermanager', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='emailsendlog',
options={'ordering': ['-creation_time'], 'verbose_name': '邮件发送log', 'verbose_name_plural': '邮件发送log'},
),
migrations.RenameField(
model_name='commands',
old_name='created_time',
new_name='creation_time',
),
migrations.RenameField(
model_name='commands',
old_name='last_mod_time',
new_name='last_modify_time',
),
migrations.RenameField(
model_name='emailsendlog',
old_name='created_time',
new_name='creation_time',
),
]

View File

@@ -6,8 +6,8 @@ class commands(models.Model):
title = models.CharField('命令标题', max_length=300)
command = models.CharField('命令', max_length=2000)
describe = models.CharField('命令描述', max_length=300)
created_time = models.DateTimeField('创建时间', auto_now_add=True)
last_mod_time = models.DateTimeField('修改时间', auto_now=True)
creation_time = models.DateTimeField('创建时间', auto_now_add=True)
last_modify_time = models.DateTimeField('修改时间', auto_now=True)
def __str__(self):
return self.title
@@ -22,7 +22,7 @@ class EmailSendLog(models.Model):
title = models.CharField('邮件标题', max_length=2000)
content = models.TextField('邮件内容')
send_result = models.BooleanField('结果', default=False)
created_time = models.DateTimeField('创建时间', auto_now_add=True)
creation_time = models.DateTimeField('创建时间', auto_now_add=True)
def __str__(self):
return self.title
@@ -30,4 +30,4 @@ class EmailSendLog(models.Model):
class Meta:
verbose_name = '邮件发送log'
verbose_name_plural = verbose_name
ordering = ['-created_time']
ordering = ['-creation_time']

View File

@@ -30,8 +30,6 @@ class ServerManagerTest(TestCase):
c = Category()
c.name = "categoryccc"
c.created_time = timezone.now()
c.last_mod_time = timezone.now()
c.save()
article = Article()

View File

@@ -1,9 +1,10 @@
{% extends 'share_layout/base_account.html' %}
{% load i18n %}
{% load static %}
{% block content %}
<div class="container">
<h2 class="form-signin-heading text-center">忘记密码</h2>
<h2 class="form-signin-heading text-center">{% trans 'forget the password' %}</h2>
<div class="card card-signin">
<img class="img-circle profile-img" src="{% static 'blog/img/avatar.png' %}" alt="">
@@ -14,8 +15,8 @@
{{ field }}
{{ field.errors }}
{% endfor %}
<input type="button" class="button" id="btn" value="获取验证码">
<button class="btn btn-lg btn-primary btn-block" type="submit">提交</button>
<input type="button" class="button" id="btn" value="{% trans 'get verification code' %}">
<button class="btn btn-lg btn-primary btn-block" type="submit">{% trans 'submit' %}</button>
</form>
</div>

View File

@@ -1,4 +1,5 @@
{% extends 'share_layout/base.html' %}
{% load i18n %}
{% block header %}
<title> {{ title }}</title>
{% endblock %}
@@ -13,9 +14,13 @@
<br/>
<header class="archive-header" style="text-align: center">
<a href="{% url "account:login" %}">登录</a>
<a href="{% url "account:login" %}">
{% trans 'login' %}
</a>
|
<a href="/">回到首页</a>
<a href="/">
{% trans 'back to the homepage' %}
</a>
</header><!-- .archive-header -->
</div>
</div>

View File

@@ -1,9 +1,10 @@
{% extends 'share_layout/base.html' %}
{% load blog_tags %}
{% load cache %}
{% load i18n %}
{% block header %}
<title>文章归档 | {{ SITE_DESCRIPTION }}</title>
<title>{% trans 'article archive' %} | {{ SITE_DESCRIPTION }}</title>
<meta name="description" content="{{ SITE_SEO_DESCRIPTION }}"/>
<meta name="keywords" content="{{ SITE_KEYWORDS }}"/>
@@ -20,7 +21,7 @@
<header class="archive-header">
<p class="archive-title">文章归档</p>
<p class="archive-title">{% trans 'article archive' %}</p>
</header><!-- .archive-header -->
<div class="entry-content">
@@ -28,11 +29,11 @@
{% regroup article_list by pub_time.year as year_post_group %}
<ul>
{% for year in year_post_group %}
<li>{{ year.grouper }}
<li>{{ year.grouper }} {% trans 'year' %}
{% regroup year.list by pub_time.month as month_post_group %}
<ul>
{% for month in month_post_group %}
<li>{{ month.grouper }}
<li>{{ month.grouper }} {% trans 'month' %}
<ul>
{% for article in month.list %}
<li><a href="{{ article.get_absolute_url }}">{{ article.title }}</a>

View File

@@ -1,5 +1,6 @@
{% load blog_tags %}
{% load cache %}
{% load i18n %}
<article id="post-{{ article.pk }} "
class="post-{{ article.pk }} post type-post status-publish format-standard hentry">
<header class="entry-header">
@@ -8,7 +9,7 @@
{% if isindex %}
{% if article.article_order > 0 %}
<a href="{{ article.get_absolute_url }}"
rel="bookmark">置顶】{{ article.title }}</a>
rel="bookmark">{% trans 'pin to top' %}】{{ article.title }}</a>
{% else %}
<a href="{{ article.get_absolute_url }}"
rel="bookmark">{{ article.title }}</a>
@@ -24,9 +25,9 @@
rel="nofollow">
<span class="leave-reply">
{% if article.comment_set and article.comment_set.count %}
{{ article.comment_set.count }}个评论
{{ article.comment_set.count }} {% trans 'comments' %}
{% else %}
发表评论
{% trans 'comment' %}
{% endif %}
</span>
</a>
@@ -54,14 +55,14 @@
{% if article.show_toc %}
{% get_markdown_toc article.body as toc %}
<b>目录:</b>
<b>{% trans 'toc' %}:</b>
{{ toc|safe }}
<hr class="break_line"/>
{% endif %}
<div class="article">
{{ article.body|custom_markdown|escape }}
{{ article.body|custom_markdown|escape }}
</div>
{% endif %}

View File

@@ -1,22 +1,25 @@
{% load blog_tags %}
{% load cache %}
{% load i18n %}
{% with article.id|add:user.is_authenticated as cachekey %}
{% cache 36000 metainfo cachekey %}
<footer class="entry-meta">
本条目发布于<a href="{{ article.get_absolute_url }}" title="{% datetimeformat article.pub_time %}"
itemprop="datePublished" content="{% datetimeformat article.pub_time %}"
rel="bookmark">
{% trans 'Published on' %}<a href="{{ article.get_absolute_url }}"
title="{% datetimeformat article.pub_time %}"
itemprop="datePublished" content="{% datetimeformat article.pub_time %}"
rel="bookmark">
<time class="entry-date updated"
datetime="{{ article.pub_time }}">
{% datetimeformat article.pub_time %}</time>
</a>
</a>
{% if article.type == 'a' %}
。属于<a href="{{ article.category.get_absolute_url }}" rel="category tag">{{ article.category.name }}</a>
分类,
{% if article.tags.all %}
被贴了
{% trans 'category' %}:
<a href="{{ article.category.get_absolute_url }}" rel="category tag">{{ article.category.name }}</a>
{% if article.tags.all %}
{% trans 'tag' %}
{% for t in article.tags.all %}
<a href="{{ t.get_absolute_url }}" rel="tag">{{ t.name }}</a>
{% if t != article.tags.all.last %}
@@ -24,13 +27,15 @@
{% endif %}
{% endfor %}
标签。
{% endif %}
{% endif %}
<span class="by-author">作者是
<span class="by-author">{% trans 'author' %}
<span class="author vcard">
<a class="url fn n" href="{{ article.author.get_absolute_url }}"
title="查看所有由{{ article.author.username }}发布的文章"
{% blocktranslate %}
title="View all articles published by {{ article.author.username }}"
{% endblocktranslate %}
rel="author">
<span itemprop="author" itemscope itemtype="http://schema.org/Person">
@@ -42,7 +47,7 @@
</a>
</span>
{% if user.is_superuser %}
<a href="{{ article.get_admin_url }}">编辑</a>
<a href="{{ article.get_admin_url }}">{% trans 'edit' %}</a>
{% endif %}
</span>
</footer><!-- .entry-meta -->

View File

@@ -1,12 +1,15 @@
{% load i18n %}
<nav id="nav-below" class="navigation" role="navigation">
<h3 class="assistive-text">文章导航</h3>
<h3 class="assistive-text">
{% trans 'article navigation' %}
</h3>
{% if page_obj.has_next and next_url%}
<div class="nav-previous"><a
href="{{ next_url }}"><span
class="meta-nav">&larr;</span> 早期文章</a></div>
class="meta-nav">&larr;</span> {% trans 'earlier articles' %}</a></div>
{% endif %}
{% if page_obj.has_previous and previous_url %}
<div class="nav-next"><a href="{{ previous_url }}">较新文章
<div class="nav-next"><a href="{{ previous_url }}">{% trans 'newer articles' %}
<span
class="meta-nav"></span></a>
</div>

View File

@@ -1,6 +1,9 @@
{% load i18n %}
{% if article_tags_list %}
<div class="panel panel-default">
<div class="panel-heading">标签</div>
<div class="panel-heading">
{% trans 'tags' %}
</div>
<div class="panel-body">
{% for url,count,tag,color in article_tags_list %}

View File

@@ -1,11 +1,12 @@
{% load blog_tags %}
{% load i18n %}
<div id="secondary" class="widget-area" role="complementary">
<aside id="search-2" class="widget widget_search">
<form role="search" method="get" id="searchform" class="searchform" action="/search">
<div>
<label class="screen-reader-text" for="s">搜索</label>
<label class="screen-reader-text" for="s">{% trans 'search' %}</label>
<input type="text" value="" name="q" id="q"/>
<input type="submit" id="searchsubmit" value="搜索"/>
<input type="submit" id="searchsubmit" />
</div>
</form>
</aside>
@@ -36,7 +37,7 @@
</aside>
{% endif %}
{% if sidebar_categorys %}
<aside id="su_siloed_terms-2" class="widget widget_su_siloed_terms"><p class="widget-title">分类目录</p>
<aside id="su_siloed_terms-2" class="widget widget_su_siloed_terms"><p class="widget-title">{% trans 'category' %}</p>
<ul>
{% for c in sidebar_categorys %}
<li class="cat-item cat-item-184"><a href={{ c.get_absolute_url }}>{{ c.name }}</a>
@@ -46,15 +47,14 @@
</aside>
{% endif %}
{% if sidebar_comments and open_site_comment %}
<aside id="ds-recent-comments-4" class="widget ds-widget-recent-comments"><p class="widget-title">近期评论</p>
{% comment %}<ul class="ds-recent-comments" data-num-items="5" data-show-avatars="1" data-show-time="1"
data-show-title="1" data-show-admin="1" data-avatar-size="30" data-excerpt-length="70"></ul>{% endcomment %}
<aside id="ds-recent-comments-4" class="widget ds-widget-recent-comments"><p class="widget-title">{% trans 'recent comments' %}</p>
<ul id="recentcomments">
{% for c in sidebar_comments %}
<li class="recentcomments">
<span class="comment-author-link">
{{ c.author.username }}</span>
发表在
{% trans 'published on' %}
<a href="{{ c.article.get_absolute_url }}#comment-{{ c.pk }}">{{ c.article.title }}</a>
</li>
{% endfor %}
@@ -62,7 +62,7 @@
</aside>
{% endif %}
{% if recent_articles %}
<aside id="recent-posts-2" class="widget widget_recent_entries"><p class="widget-title">近期文章</p>
<aside id="recent-posts-2" class="widget widget_recent_entries"><p class="widget-title">{% trans 'recent articles' %}</p>
<ul>
{% for a in recent_articles %}
@@ -74,7 +74,7 @@
</aside>
{% endif %}
{% if sidabar_links %}
<aside id="linkcat-0" class="widget widget_links"><p class="widget-title">书签</p>
<aside id="linkcat-0" class="widget widget_links"><p class="widget-title">{% trans 'bookmark' %}</p>
<ul class='xoxo blogroll'>
{% for l in sidabar_links %}
<li>
@@ -93,7 +93,7 @@
</aside>
{% endif %}
{% if sidebar_tags %}
<aside id="tag_cloud-2" class="widget widget_tag_cloud"><p class="widget-title">标签云</p>
<aside id="tag_cloud-2" class="widget widget_tag_cloud"><p class="widget-title">{% trans 'Tag Cloud' %}</p>
<div class="tagcloud">
{% for tag,count,size in sidebar_tags %}
<a href="{{ tag.get_absolute_url }}"
@@ -104,7 +104,7 @@
</div>
</aside>
{% endif %}
<aside id="text-2" class="widget widget_text"><p class="widget-title">欢迎您star或者fork本站源代码</p>
<aside id="text-2" class="widget widget_text"><p class="widget-title">{% trans 'Welcome to star or fork the source code of this site' %}</p>
<div class="textwidget">
<p><a href="https://github.com/liangliangyy/DjangoBlog" rel="nofollow"><img
@@ -115,22 +115,22 @@
</div>
</aside>
<aside id="meta-3" class="widget widget_meta"><p class="widget-title">功能</p>
<aside id="meta-3" class="widget widget_meta"><p class="widget-title">{% trans 'Function' %}</p>
<ul>
<li><a href="/admin/" rel="nofollow">管理站点</a></li>
<li><a href="/admin/" rel="nofollow">{% trans 'management site' %}</a></li>
{% if user.is_authenticated %}
<li><a href="{% url "account:logout" %}" rel="nofollow">登出</a>
<li><a href="{% url "account:logout" %}" rel="nofollow">{% trans 'logout' %}</a>
</li>
{% else %}
<li><a href="{% url "account:login" %}" rel="nofollow">登录</a></li>
<li><a href="{% url "account:login" %}" rel="nofollow">{% trans 'login' %}</a></li>
{% endif %}
{% if user.is_superuser %}
<li><a href="{% url 'owntracks:show_dates' %}" target="_blank">运动轨迹记录</a></li>
<li><a href="{% url 'owntracks:show_dates' %}" target="_blank">{% trans 'Track record' %}</a></li>
{% endif %}
<li><a href="http://gitbook.lylinux.net" target="_blank" rel="nofollow">GitBook</a></li>
</ul>
</aside>
<div id="rocket" class="show" title="点我返回顶部"></div>
<div id="rocket" class="show" title="{% trans 'Click me to return to the top' %}"></div>
</div><!-- #secondary -->

View File

@@ -21,7 +21,7 @@
</div>
<div class="comment-meta commentmetadata">
<div>{{ comment_item.created_time }}</div>
<div>{{ comment_item.creation_time }}</div>
<div>回复给:@{{ comment_item.author.parent_comment.username }}</div>
</div>
<p>{{ comment_item.body|escape|comment_markdown }}</p>

View File

@@ -22,7 +22,7 @@
</div>
<div class="comment-meta commentmetadata">
{{ comment_item.created_time }}
{{ comment_item.creation_time }}
</div>
<p>
{% if comment_item.parent_comment %}

View File

@@ -1,5 +1,6 @@
{% load static %}
{% load cache %}
{% load i18n %}
{% load compress %}
<!DOCTYPE html>
<!--[if IE 7]>
@@ -57,6 +58,24 @@
</h1>
<h2 class="site-description">{{ SITE_DESCRIPTION }}</h2>
</hgroup>
{% load i18n %}
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}">
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go">
</form>
{% cache 36000 nav %}
{% include 'share_layout/nav.html' %}