Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加多语言支持 #679

Merged
merged 4 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
bin/data/
# virtualenv
venv/
migrations/
!migrations/__init__.py
collectedstatic/
djangoblog/whoosh_index/
uploads/
Expand Down
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
FROM python:3
ENV PYTHONUNBUFFERED 1
WORKDIR /code/djangoblog/
RUN apt-get install default-libmysqlclient-dev -y && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN apt-get update && \
apt-get install default-libmysqlclient-dev gettext -y && \
rm -rf /var/lib/apt/lists/*
ADD requirements.txt requirements.txt
RUN pip install --upgrade pip && \
pip install --no-cache-dir -r requirements.txt && \
Expand Down
17 changes: 3 additions & 14 deletions accounts/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django import forms
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth.forms import UsernameField
from django.utils.translation import gettext_lazy as _
Expand All @@ -10,8 +9,8 @@


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
Expand All @@ -22,7 +21,7 @@ def clean_password2(self):
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):
Expand All @@ -36,16 +35,6 @@ def save(self, commit=True):


class BlogUserChangeForm(UserChangeForm):
password = ReadOnlyPasswordHashField(
label=_("Password"),
help_text=_(
"Raw passwords are not stored, so there is no way to see this "
"user's password, but you can change the password using "
"<a href=\"{}\">this form</a>."
),
)
email = forms.EmailField(label="Email", widget=forms.EmailInput)

class Meta:
model = BlogUser
fields = '__all__'
Expand Down
22 changes: 11 additions & 11 deletions accounts/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
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

Expand Down Expand Up @@ -33,7 +33,7 @@ def __init__(self, *args, **kwargs):
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:
Expand All @@ -43,11 +43,11 @@ class Meta:

class ForgetPasswordForm(forms.Form):
new_password1 = forms.CharField(
label="新密码",
label=_("New password"),
widget=forms.PasswordInput(
attrs={
"class": "form-control",
'placeholder': "密码"
'placeholder': _("New password")
}
),
)
Expand All @@ -57,7 +57,7 @@ class ForgetPasswordForm(forms.Form):
widget=forms.PasswordInput(
attrs={
"class": "form-control",
'placeholder': "确认密码"
'placeholder': _("Confirm password")
}
),
)
Expand All @@ -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")
}
),
)
Expand All @@ -86,7 +86,7 @@ def clean_new_password2(self):
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
Expand All @@ -97,7 +97,7 @@ def clean_email(self):
email=user_email
).exists():
# todo 这里的报错提示可以判断一个邮箱是不是注册过,如果不想暴露可以修改
raise ValidationError("未找到邮箱对应的用户")
raise ValidationError(_("email does not exist"))
return user_email

def clean_code(self):
Expand All @@ -113,5 +113,5 @@ def clean_code(self):

class ForgetPasswordCodeForm(forms.Form):
email = forms.EmailField(
label="邮箱号"
label=_('Email'),
)
Original file line number Diff line number Diff line change
@@ -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'),
),
]
12 changes: 6 additions & 6 deletions accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
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(
Expand All @@ -30,6 +30,6 @@ def get_full_url(self):

class Meta:
ordering = ['-id']
verbose_name = "用户"
verbose_name = _('user')
verbose_name_plural = verbose_name
get_latest_by = 'id'
16 changes: 8 additions & 8 deletions accounts/tests.py
Original file line number Diff line number Diff line change
@@ -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


Expand Down Expand Up @@ -39,8 +39,8 @@ def test_validate_account(self):

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()
Expand Down Expand Up @@ -86,8 +86,8 @@ def test_validate_register(self):
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()
Expand Down Expand Up @@ -191,7 +191,7 @@ def test_forget_password_email_not_user(self):
response=resp,
form="form",
field="email",
errors="未找到邮箱对应的用户"
errors=_("email does not exist")
)

def test_forget_password_email_code_error(self):
Expand All @@ -213,5 +213,5 @@ def test_forget_password_email_code_error(self):
response=resp,
form="form",
field="code",
errors="验证码错误"
errors=_('Verification code error')
)
24 changes: 12 additions & 12 deletions accounts/urls.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
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

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'),
]
10 changes: 7 additions & 3 deletions accounts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,24 @@
from datetime import timedelta

from django.core.cache import cache
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _

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 = _(
"You are resetting the password, the verification code is:%(code)s, valid within 5 minutes, please keep it "
"properly") % {'code': code}
send_email([to_mail], subject, html_content)


Expand All @@ -32,7 +36,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):
Expand Down
2 changes: 1 addition & 1 deletion accounts/views.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading
Loading