Переглянути джерело

完善了数据库结构,完成了基于allauth的邮件验证系统

Shellmiao 4 роки тому
батько
коміт
54fcaa9cda
54 змінених файлів з 681 додано та 2 видалено
  1. 0 0
      CrawKeywords/__init__.py
  2. 20 0
      CrawKeywords/admin.py
  3. 6 0
      CrawKeywords/apps.py
  4. 45 0
      CrawKeywords/migrations/0001_initial.py
  5. 0 0
      CrawKeywords/migrations/__init__.py
  6. 35 0
      CrawKeywords/models.py
  7. 3 0
      CrawKeywords/tests.py
  8. 0 0
      CrawKeywords/urls.py
  9. 3 0
      CrawKeywords/views.py
  10. 0 0
      Profile/__init__.py
  11. 10 0
      Profile/admin.py
  12. 6 0
      Profile/apps.py
  13. 25 0
      Profile/migrations/0001_initial.py
  14. 0 0
      Profile/migrations/__init__.py
  15. 13 0
      Profile/models.py
  16. 3 0
      Profile/tests.py
  17. 3 0
      Profile/views.py
  18. 53 1
      WeiBoCrawler/settings.py
  19. 3 1
      WeiBoCrawler/urls.py
  20. 11 0
      templates/account/account_inactive.html
  21. 40 0
      templates/account/base.html
  22. 74 0
      templates/account/email.html
  23. 7 0
      templates/account/email/base_message.txt
  24. 7 0
      templates/account/email/email_confirmation_message.txt
  25. 1 0
      templates/account/email/email_confirmation_signup_message.txt
  26. 1 0
      templates/account/email/email_confirmation_signup_subject.txt
  27. 4 0
      templates/account/email/email_confirmation_subject.txt
  28. 9 0
      templates/account/email/password_reset_key_message.txt
  29. 4 0
      templates/account/email/password_reset_key_subject.txt
  30. 31 0
      templates/account/email_confirm.html
  31. 46 0
      templates/account/login.html
  32. 21 0
      templates/account/logout.html
  33. 2 0
      templates/account/messages/cannot_delete_primary_email.txt
  34. 2 0
      templates/account/messages/email_confirmation_sent.txt
  35. 2 0
      templates/account/messages/email_confirmed.txt
  36. 2 0
      templates/account/messages/email_deleted.txt
  37. 4 0
      templates/account/messages/logged_in.txt
  38. 2 0
      templates/account/messages/logged_out.txt
  39. 2 0
      templates/account/messages/password_changed.txt
  40. 2 0
      templates/account/messages/password_set.txt
  41. 2 0
      templates/account/messages/primary_email_set.txt
  42. 2 0
      templates/account/messages/unverified_primary_email.txt
  43. 16 0
      templates/account/password_change.html
  44. 24 0
      templates/account/password_reset.html
  45. 16 0
      templates/account/password_reset_done.html
  46. 23 0
      templates/account/password_reset_from_key.html
  47. 9 0
      templates/account/password_reset_from_key_done.html
  48. 15 0
      templates/account/password_set.html
  49. 21 0
      templates/account/signup.html
  50. 11 0
      templates/account/signup_closed.html
  51. 5 0
      templates/account/snippets/already_logged_in.html
  52. 12 0
      templates/account/verification_sent.html
  53. 23 0
      templates/account/verified_email_required.html
  54. BIN
      设计原型图/数据库结构.png

+ 0 - 0
CrawKeywords/__init__.py


+ 20 - 0
CrawKeywords/admin.py

@@ -0,0 +1,20 @@
+from django.contrib import admin
+from .models import KeywordMission, DateMission, TimeMission
+
+
+# Register your models here.
+class KeywordMissionAdmin(admin.ModelAdmin):
+    list_display = ["keyword_mission_id", "keyword"]
+
+
+class DateMissionAdmin(admin.ModelAdmin):
+    list_display = ["date_mission_id", "date", "is_date_finished", "keyword_mission"]
+
+
+class TimeMissionAdmin(admin.ModelAdmin):
+    list_display = ["time_mission_id", "time", "is_time_finished", "keyword_mission", "date_mission"]
+
+
+admin.site.register(KeywordMission, KeywordMissionAdmin)
+admin.site.register(DateMission, DateMissionAdmin)
+admin.site.register(TimeMission, TimeMissionAdmin)

+ 6 - 0
CrawKeywords/apps.py

@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class CrawkeywordsConfig(AppConfig):
+    default_auto_field = 'django.db.models.BigAutoField'
+    name = 'CrawKeywords'

+ 45 - 0
CrawKeywords/migrations/0001_initial.py

@@ -0,0 +1,45 @@
+# Generated by Django 3.2.5 on 2021-07-30 16:07
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='DateMission',
+            fields=[
+                ('date_mission_id', models.AutoField(primary_key=True, serialize=False)),
+                ('date', models.DateField()),
+                ('is_date_finished', models.BooleanField(default=False)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='KeywordMission',
+            fields=[
+                ('keyword_mission_id', models.AutoField(primary_key=True, serialize=False)),
+                ('keyword', models.CharField(max_length=256)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='TimeMission',
+            fields=[
+                ('time_mission_id', models.AutoField(primary_key=True, serialize=False)),
+                ('time', models.DateTimeField()),
+                ('is_time_finished', models.BooleanField(default=False)),
+                ('date_mission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='TimeMission', to='CrawKeywords.datemission')),
+                ('keyword_mission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='TimeMission', to='CrawKeywords.keywordmission')),
+            ],
+        ),
+        migrations.AddField(
+            model_name='datemission',
+            name='keyword_mission',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='DateMission', to='CrawKeywords.keywordmission'),
+        ),
+    ]

+ 0 - 0
CrawKeywords/migrations/__init__.py


+ 35 - 0
CrawKeywords/models.py

@@ -0,0 +1,35 @@
+from django.db import models
+
+
+#  关键词任务表
+class KeywordMission(models.Model):
+    # 关键词任务id
+    keyword_mission_id = models.AutoField(primary_key=True)
+    # 关键词
+    keyword = models.CharField(max_length=256)
+
+
+#  日期任务表
+class DateMission(models.Model):
+    # 日期任务id
+    date_mission_id = models.AutoField(primary_key=True)
+    # 日期
+    date = models.DateField()
+    # 是否已完成
+    is_date_finished = models.BooleanField(default=False)
+    # 关键词任务
+    keyword_mission = models.ForeignKey(KeywordMission, on_delete=models.CASCADE, related_name='DateMission')
+
+
+#  时间任务表
+class TimeMission(models.Model):
+    # 时间任务id
+    time_mission_id = models.AutoField(primary_key=True)
+    # 时间
+    time = models.DateTimeField()
+    # 是否已完成
+    is_time_finished = models.BooleanField(default=False)
+    # 关键词任务
+    keyword_mission = models.ForeignKey(KeywordMission, on_delete=models.CASCADE, related_name='TimeMission')
+    # 日期任务
+    date_mission = models.ForeignKey(DateMission, on_delete=models.CASCADE, related_name='TimeMission')

+ 3 - 0
CrawKeywords/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 0 - 0
CrawKeywords/urls.py


+ 3 - 0
CrawKeywords/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 0 - 0
Profile/__init__.py


+ 10 - 0
Profile/admin.py

@@ -0,0 +1,10 @@
+from django.contrib import admin
+from .models import Profile
+
+
+# Register your models here.
+class ProfileAdmin(admin.ModelAdmin):
+    list_display = ["user", "contribution"]
+
+
+admin.site.register(Profile, ProfileAdmin)

+ 6 - 0
Profile/apps.py

@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class ProfileConfig(AppConfig):
+    default_auto_field = 'django.db.models.BigAutoField'
+    name = 'Profile'

+ 25 - 0
Profile/migrations/0001_initial.py

@@ -0,0 +1,25 @@
+# Generated by Django 3.2.5 on 2021-07-30 16:21
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Profile',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('contribution', models.BigIntegerField()),
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
+            ],
+        ),
+    ]

+ 0 - 0
Profile/migrations/__init__.py


+ 13 - 0
Profile/models.py

@@ -0,0 +1,13 @@
+from django.db import models
+from django.contrib.auth.models import User
+
+
+# 用户信息
+class Profile(models.Model):
+    # 对应django自带的user
+    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
+    # 贡献度
+    contribution = models.BigIntegerField()
+
+    def __str__(self):
+        return 'user {}'.format(self.user.username)

+ 3 - 0
Profile/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
Profile/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 53 - 1
WeiBoCrawler/settings.py

@@ -35,6 +35,13 @@ INSTALLED_APPS = [
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
+    'CrawKeywords',
+    'Profile',
+    # The following apps are required:
+    'django.contrib.sites',
+    'allauth',
+    'allauth.account',
+    'allauth.socialaccount',
 ]
 
 MIDDLEWARE = [
@@ -52,7 +59,7 @@ ROOT_URLCONF = 'WeiBoCrawler.urls'
 TEMPLATES = [
     {
         'BACKEND': 'django.template.backends.django.DjangoTemplates',
-        'DIRS': [],
+        'DIRS': [os.path.join(BASE_DIR, 'templates')],
         'APP_DIRS': True,
         'OPTIONS': {
             'context_processors': [
@@ -60,10 +67,52 @@ TEMPLATES = [
                 'django.template.context_processors.request',
                 'django.contrib.auth.context_processors.auth',
                 'django.contrib.messages.context_processors.messages',
+                'django.template.context_processors.request',
             ],
         },
     },
 ]
+# django-allauth基本配置
+ACCOUNT_AUTHENTICATION_METHOD = 'username_email'  # 可以使用用户名或邮箱登录
+
+ACCOUNT_EMAIL_REQUIRED = True  # 必须设置电子邮箱
+
+LOGIN_REDIRECT_URL = '/'  # 登录成功后的跳转地址
+
+ACCOUNT_LOGOUT_REDIRECT_URL = '/'  # 退出登录后跳转链接
+
+# 发送邮件配置项
+# SMTP服务器地址
+EMAIL_HOST = 'smtp.exmail.qq.com'
+# 端口
+EMAIL_PORT = 25
+# 发送邮件的邮箱
+EMAIL_HOST_USER = 'shellmiao@shellmiao.com'
+# 在邮箱中设置的客户端授权密码
+EMAIL_HOST_PASSWORD = 'KU3awdLM2MnDqdbM'
+
+EMAIL_USE_TLS = True
+# 收件人看到的发件人
+EMAIL_FROM = 'shellmiao<shellmiao@shellmiao.com>'
+# 报错此项必须加上
+DEFAULT_FROM_EMAIL = 'shellmiao@shellmiao.com'
+
+AUTHENTICATION_BACKENDS = [
+    # Needed to login by username in Django admin, regardless of `allauth`
+    'django.contrib.auth.backends.ModelBackend',
+    # `allauth` specific authentication methods, such as login by e-mail
+    'allauth.account.auth_backends.AuthenticationBackend',
+]
+# 注册中邮件验证方法
+ACCOUNT_EMAIL_VERIFICATION = "mandatory"
+# 邮件发送后的冷却时间(以秒为单位)
+ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN = 180
+# 登录尝试失败的次数
+ACCOUNT_LOGIN_ATTEMPTS_LIMIT = 5
+# 从上次失败的登录尝试,用户被禁止尝试登录的持续时间
+ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT = 300
+# 电子邮件地址的唯一性
+ACCOUNT_UNIQUE_EMAIL = True
 
 WSGI_APPLICATION = 'WeiBoCrawler.wsgi.application'
 
@@ -99,6 +148,9 @@ AUTH_PASSWORD_VALIDATORS = [
     },
 ]
 
+# allauth
+SITE_ID = 1
+
 # Internationalization
 # https://docs.djangoproject.com/en/2.0/topics/i18n/
 

+ 3 - 1
WeiBoCrawler/urls.py

@@ -14,8 +14,10 @@ Including another URLconf
     2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
 """
 from django.contrib import admin
-from django.urls import path
+from django.urls import path, include
 
 urlpatterns = [
     path('admin/', admin.site.urls),
+#    path('craw_keywords/', include(('CrawKeywords.urls', "CrawKeywords"), namespace='CrawKeywords')),
+    path('accounts/', include('allauth.urls')),
 ]

+ 11 - 0
templates/account/account_inactive.html

@@ -0,0 +1,11 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "Account Inactive" %}{% endblock %}
+
+{% block content %}
+<h1>{% trans "Account Inactive" %}</h1>
+
+<p>{% trans "This account is inactive." %}</p>
+{% endblock %}

+ 40 - 0
templates/account/base.html

@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>{% block head_title %}{% endblock %}</title>
+    {% block extra_head %}
+    {% endblock %}
+  </head>
+  <body>
+    {% block body %}
+
+    {% if messages %}
+    <div>
+      <strong>Messages:</strong>
+      <ul>
+        {% for message in messages %}
+        <li>{{message}}</li>
+        {% endfor %}
+      </ul>
+    </div>
+    {% endif %}
+
+    <div>
+      <strong>Menu:</strong>
+      <ul>
+        {% if user.is_authenticated %}
+        <li><a href="{% url 'account_email' %}">Change E-mail</a></li>
+        <li><a href="{% url 'account_logout' %}">Sign Out</a></li>
+        {% else %}
+        <li><a href="{% url 'account_login' %}">Sign In</a></li>
+        <li><a href="{% url 'account_signup' %}">Sign Up</a></li>
+        {% endif %}
+      </ul>
+    </div>
+    {% block content %}
+    {% endblock %}
+    {% endblock %}
+    {% block extra_body %}
+    {% endblock %}
+  </body>
+</html>

+ 74 - 0
templates/account/email.html

@@ -0,0 +1,74 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "E-mail Addresses" %}{% endblock %}
+
+{% block content %}
+    <h1>{% trans "E-mail Addresses" %}</h1>
+{% if user.emailaddress_set.all %}
+<p>{% trans 'The following e-mail addresses are associated with your account:' %}</p>
+
+<form action="{% url 'account_email' %}" class="email_list" method="post">
+{% csrf_token %}
+<fieldset class="blockLabels">
+
+  {% for emailaddress in user.emailaddress_set.all %}
+<div class="ctrlHolder">
+      <label for="email_radio_{{forloop.counter}}" class="{% if emailaddress.primary %}primary_email{%endif%}">
+
+      <input id="email_radio_{{forloop.counter}}" type="radio" name="email" {% if emailaddress.primary or user.emailaddress_set.count == 1 %}checked="checked"{%endif %} value="{{emailaddress.email}}"/>
+
+{{ emailaddress.email }}
+    {% if emailaddress.verified %}
+    <span class="verified">{% trans "Verified" %}</span>
+    {% else %}
+    <span class="unverified">{% trans "Unverified" %}</span>
+    {% endif %}
+      {% if emailaddress.primary %}<span class="primary">{% trans "Primary" %}</span>{% endif %}
+</label>
+</div>
+  {% endfor %}
+
+<div class="buttonHolder">
+      <button class="secondaryAction" type="submit" name="action_primary" >{% trans 'Make Primary' %}</button>
+      <button class="secondaryAction" type="submit" name="action_send" >{% trans 'Re-send Verification' %}</button>
+      <button class="primaryAction" type="submit" name="action_remove" >{% trans 'Remove' %}</button>
+</div>
+
+</fieldset>
+</form>
+
+{% else %}
+<p><strong>{% trans 'Warning:'%}</strong> {% trans "You currently do not have any e-mail address set up. You should really add an e-mail address so you can receive notifications, reset your password, etc." %}</p>
+
+{% endif %}
+
+  {% if can_add_email %}
+    <h2>{% trans "Add E-mail Address" %}</h2>
+
+    <form method="post" action="{% url 'account_email' %}" class="add_email">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <button name="action_add" type="submit">{% trans "Add E-mail" %}</button>
+    </form>
+  {% endif %}
+
+{% endblock %}
+
+
+{% block extra_body %}
+<script type="text/javascript">
+(function() {
+  var message = "{% trans 'Do you really want to remove the selected e-mail address?' %}";
+  var actions = document.getElementsByName('action_remove');
+  if (actions.length) {
+    actions[0].addEventListener("click", function(e) {
+      if (! confirm(message)) {
+        e.preventDefault();
+      }
+    });
+  }
+})();
+</script>
+{% endblock %}

+ 7 - 0
templates/account/email/base_message.txt

@@ -0,0 +1,7 @@
+{% load i18n %}{% autoescape off %}{% blocktrans with site_name=current_site.name %}Hello from {{ site_name }}!{% endblocktrans %}
+
+{% block content %}{% endblock %}
+
+{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}感谢您使用 {{ site_name }}!
+{{ site_domain }}{% endblocktrans %}
+{% endautoescape %}

+ 7 - 0
templates/account/email/email_confirmation_message.txt

@@ -0,0 +1,7 @@
+{% extends "account/email/base_message.txt" %}
+{% load account %}
+{% load i18n %}
+
+{% block content %}{% autoescape off %}{% user_display user as user_display %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}用户 {{ user_display }} 正在注册 [公众舆情分析系统] : {{ site_domain }} .
+
+前往地址 {{ activate_url }} 来验证您的身份 {% endblocktrans %}{% endautoescape %}{% endblock %}

+ 1 - 0
templates/account/email/email_confirmation_signup_message.txt

@@ -0,0 +1 @@
+{% include "account/email/email_confirmation_message.txt" %}

+ 1 - 0
templates/account/email/email_confirmation_signup_subject.txt

@@ -0,0 +1 @@
+{% include "account/email/email_confirmation_subject.txt" %}

+ 4 - 0
templates/account/email/email_confirmation_subject.txt

@@ -0,0 +1,4 @@
+{% load i18n %}
+{% autoescape off %}
+{% blocktrans %}[公众舆情分析系统]请验证邮箱{% endblocktrans %}
+{% endautoescape %}

+ 9 - 0
templates/account/email/password_reset_key_message.txt

@@ -0,0 +1,9 @@
+{% extends "account/email/base_message.txt" %}
+{% load i18n %}
+
+{% block content %}{% autoescape off %}{% blocktrans %}You're receiving this e-mail because you or someone else has requested a password for your user account.
+It can be safely ignored if you did not request a password reset. Click the link below to reset your password.{% endblocktrans %}
+
+{{ password_reset_url }}{% if username %}
+
+{% blocktrans %}In case you forgot, your username is {{ username }}.{% endblocktrans %}{% endif %}{% endautoescape %}{% endblock %}

+ 4 - 0
templates/account/email/password_reset_key_subject.txt

@@ -0,0 +1,4 @@
+{% load i18n %}
+{% autoescape off %}
+{% blocktrans %}Password Reset E-mail{% endblocktrans %}
+{% endautoescape %}

+ 31 - 0
templates/account/email_confirm.html

@@ -0,0 +1,31 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+{% load account %}
+
+{% block head_title %}{% trans "Confirm E-mail Address" %}{% endblock %}
+
+
+{% block content %}
+<h1>{% trans "Confirm E-mail Address" %}</h1>
+
+{% if confirmation %}
+
+{% user_display confirmation.email_address.user as user_display %}
+
+<p>{% blocktrans with confirmation.email_address.email as email %}Please confirm that <a href="mailto:{{ email }}">{{ email }}</a> is an e-mail address for user {{ user_display }}.{% endblocktrans %}</p>
+
+<form method="post" action="{% url 'account_confirm_email' confirmation.key %}">
+{% csrf_token %}
+    <button type="submit">{% trans 'Confirm' %}</button>
+</form>
+
+{% else %}
+
+{% url 'account_email' as email_url %}
+
+<p>{% blocktrans %}This e-mail confirmation link expired or is invalid. Please <a href="{{ email_url }}">issue a new e-mail confirmation request</a>.{% endblocktrans %}</p>
+
+{% endif %}
+
+{% endblock %}

+ 46 - 0
templates/account/login.html

@@ -0,0 +1,46 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+{% load account socialaccount %}
+
+{% block head_title %}{% trans "Sign In" %}{% endblock %}
+
+{% block content %}
+
+<h1>{% trans "Sign In" %}</h1>
+
+{% get_providers as socialaccount_providers %}
+
+{% if socialaccount_providers %}
+<p>{% blocktrans with site.name as site_name %}Please sign in with one
+of your existing third party accounts. Or, <a href="{{ signup_url }}">sign up</a>
+for a {{ site_name }} account and sign in below:{% endblocktrans %}</p>
+
+<div class="socialaccount_ballot">
+
+  <ul class="socialaccount_providers">
+    {% include "socialaccount/snippets/provider_list.html" with process="login" %}
+  </ul>
+
+  <div class="login-or">{% trans 'or' %}</div>
+
+</div>
+
+{% include "socialaccount/snippets/login_extra.html" %}
+
+{% else %}
+<p>{% blocktrans %}If you have not hhhhhhhhhhhhhhhhhhhhhcreated an account yet, then please
+<a href="{{ signup_url }}">sign up</a> first.{% endblocktrans %}</p>
+{% endif %}
+
+<form class="login" method="POST" action="{% url 'account_login' %}">
+  {% csrf_token %}
+  {{ form.as_p }}
+  {% if redirect_field_value %}
+  <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
+  {% endif %}
+  <a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
+  <button class="primaryAction" type="submit">{% trans "Sign In" %}</button>
+</form>
+
+{% endblock %}

+ 21 - 0
templates/account/logout.html

@@ -0,0 +1,21 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "Sign Out" %}{% endblock %}
+
+{% block content %}
+<h1>{% trans "Sign Out" %}</h1>
+
+<p>{% trans 'Are you sure you want to sign out?' %}</p>
+
+<form method="post" action="{% url 'account_logout' %}">
+  {% csrf_token %}
+  {% if redirect_field_value %}
+  <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}"/>
+  {% endif %}
+  <button type="submit">{% trans 'Sign Out' %}</button>
+</form>
+
+
+{% endblock %}

+ 2 - 0
templates/account/messages/cannot_delete_primary_email.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}You cannot remove your primary e-mail address ({{email}}).{% endblocktrans %}

+ 2 - 0
templates/account/messages/email_confirmation_sent.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}Confirmation e-mail sent to {{email}}.{% endblocktrans %}

+ 2 - 0
templates/account/messages/email_confirmed.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}You have confirmed {{email}}.{% endblocktrans %}

+ 2 - 0
templates/account/messages/email_deleted.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}Removed e-mail address {{email}}.{% endblocktrans %}

+ 4 - 0
templates/account/messages/logged_in.txt

@@ -0,0 +1,4 @@
+{% load account %}
+{% load i18n %}
+{% user_display user as name %}
+{% blocktrans %}Successfully signed in as {{name}}.{% endblocktrans %}

+ 2 - 0
templates/account/messages/logged_out.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}You have signed out.{% endblocktrans %}

+ 2 - 0
templates/account/messages/password_changed.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}Password successfully changed.{% endblocktrans %}

+ 2 - 0
templates/account/messages/password_set.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}Password successfully set.{% endblocktrans %}

+ 2 - 0
templates/account/messages/primary_email_set.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}Primary e-mail address set.{% endblocktrans %}

+ 2 - 0
templates/account/messages/unverified_primary_email.txt

@@ -0,0 +1,2 @@
+{% load i18n %}
+{% blocktrans %}Your primary e-mail address must be verified.{% endblocktrans %}

+ 16 - 0
templates/account/password_change.html

@@ -0,0 +1,16 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "Change Password" %}{% endblock %}
+
+{% block content %}
+    <h1>{% trans "Change Password" %}</h1>
+
+    <form method="POST" action="{% url 'account_change_password' %}" class="password_change">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <button type="submit" name="action">{% trans "Change Password" %}</button>
+        <a href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
+    </form>
+{% endblock %}

+ 24 - 0
templates/account/password_reset.html

@@ -0,0 +1,24 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+{% load account %}
+
+{% block head_title %}{% trans "Password Reset" %}{% endblock %}
+
+{% block content %}
+
+    <h1>{% trans "Password Reset" %}</h1>
+    {% if user.is_authenticated %}
+    {% include "account/snippets/already_logged_in.html" %}
+    {% endif %}
+
+    <p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." %}</p>
+
+    <form method="POST" action="{% url 'account_reset_password' %}" class="password_reset">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <input type="submit" value="{% trans 'Reset My Password' %}" />
+    </form>
+
+    <p>{% blocktrans %}Please contact us if you have any trouble resetting your password.{% endblocktrans %}</p>
+{% endblock %}

+ 16 - 0
templates/account/password_reset_done.html

@@ -0,0 +1,16 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+{% load account %}
+
+{% block head_title %}{% trans "Password Reset" %}{% endblock %}
+
+{% block content %}
+    <h1>{% trans "Password Reset" %}</h1>
+    
+    {% if user.is_authenticated %}
+    {% include "account/snippets/already_logged_in.html" %}
+    {% endif %}
+    
+    <p>{% blocktrans %}We have sent you an e-mail. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}</p>
+{% endblock %}

+ 23 - 0
templates/account/password_reset_from_key.html

@@ -0,0 +1,23 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+{% block head_title %}{% trans "Change Password" %}{% endblock %}
+
+{% block content %}
+    <h1>{% if token_fail %}{% trans "Bad Token" %}{% else %}{% trans "Change Password" %}{% endif %}</h1>
+
+    {% if token_fail %}
+        {% url 'account_reset_password' as passwd_reset_url %}
+        <p>{% blocktrans %}The password reset link was invalid, possibly because it has already been used.  Please request a <a href="{{ passwd_reset_url }}">new password reset</a>.{% endblocktrans %}</p>
+    {% else %}
+        {% if form %}
+            <form method="POST" action="{{ action_url }}">
+                {% csrf_token %}
+                {{ form.as_p }}
+                <input type="submit" name="action" value="{% trans 'change password' %}"/>
+            </form>
+        {% else %}
+            <p>{% trans 'Your password is now changed.' %}</p>
+        {% endif %}
+    {% endif %}
+{% endblock %}

+ 9 - 0
templates/account/password_reset_from_key_done.html

@@ -0,0 +1,9 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+{% block head_title %}{% trans "Change Password" %}{% endblock %}
+
+{% block content %}
+    <h1>{% trans "Change Password" %}</h1>
+    <p>{% trans 'Your password is now changed.' %}</p>
+{% endblock %}

+ 15 - 0
templates/account/password_set.html

@@ -0,0 +1,15 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "Set Password" %}{% endblock %}
+
+{% block content %}
+    <h1>{% trans "Set Password" %}</h1>
+
+    <form method="POST" action="{% url 'account_set_password' %}" class="password_set">
+        {% csrf_token %}
+        {{ form.as_p }}
+        <input type="submit" name="action" value="{% trans 'Set Password' %}"/>
+    </form>
+{% endblock %}

+ 21 - 0
templates/account/signup.html

@@ -0,0 +1,21 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "Signup" %}{% endblock %}
+
+{% block content %}
+<h1>{% trans "Sign Up" %}</h1>
+
+<p>{% blocktrans %}Already have an account? Then please <a href="{{ login_url }}">sign in</a>.{% endblocktrans %}</p>
+
+<form class="signup" id="signup_form" method="post" action="{% url 'account_signup' %}">
+  {% csrf_token %}
+  {{ form.as_p }}
+  {% if redirect_field_value %}
+  <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
+  {% endif %}
+  <button type="submit">{% trans "Sign Up" %} &raquo;</button>
+</form>
+
+{% endblock %}

+ 11 - 0
templates/account/signup_closed.html

@@ -0,0 +1,11 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "Sign Up Closed" %}{% endblock %}
+
+{% block content %}
+<h1>{% trans "Sign Up Closed" %}</h1>
+
+<p>{% trans "We are sorry, but the sign up is currently closed." %}</p>
+{% endblock %}

+ 5 - 0
templates/account/snippets/already_logged_in.html

@@ -0,0 +1,5 @@
+{% load i18n %}
+{% load account %}
+
+{% user_display user as user_display %}
+<p><strong>{% trans "Note" %}:</strong> {% blocktrans %}you are already logged in as {{ user_display }}.{% endblocktrans %}</p>

+ 12 - 0
templates/account/verification_sent.html

@@ -0,0 +1,12 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %}
+
+{% block content %}
+    <h1>{% trans "Verify Your E-mail Address" %}</h1>
+
+    <p>{% blocktrans %}We have sent an e-mail to you for verification. Follow the link provided to finalize the signup process. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}</p>
+
+{% endblock %}

+ 23 - 0
templates/account/verified_email_required.html

@@ -0,0 +1,23 @@
+{% extends "account/base.html" %}
+
+{% load i18n %}
+
+{% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %}
+
+{% block content %}
+<h1>{% trans "Verify Your E-mail Address" %}</h1>
+
+{% url 'account_email' as email_url %}
+
+<p>{% blocktrans %}This part of the site requires us to verify that
+you are who you claim to be. For this purpose, we require that you
+verify ownership of your e-mail address. {% endblocktrans %}</p>
+
+<p>{% blocktrans %}We have sent an e-mail to you for
+verification. Please click on the link inside this e-mail. Please
+contact us if you do not receive it within a few minutes.{% endblocktrans %}</p>
+
+<p>{% blocktrans %}<strong>Note:</strong> you can still <a href="{{ email_url }}">change your e-mail address</a>.{% endblocktrans %}</p>
+
+
+{% endblock %}

BIN
设计原型图/数据库结构.png