django-allauth:用户个人资料UserProfile扩展与编辑

文章转载于:https://mp.weixin.qq.com/s/ZUzI8gcZAqwbERuLdBQAwQ

第一步 创建应用及配置

由于django-allauth已经占用了account这个app名,所以我们需要先创建一个叫myaccount的app,并将其加入到settings.py配置文件INSTALLED_APP里去,同时把urls也加入到项目的urls里去


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myaccount',   # 创建的app
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.weibo',
]

根urls.py文件中,使用一样的accounts的路径,

urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')),
    path('accounts/', include('myaccount.urls')),
] 

因为我们希望用户在登录或注册后自动跳转到/accounts/profile/, 我们可以在settings.py中加入以下代码。

LOGIN_REDIRECT_URL = '/accounts/profile/'

第二步 编写模型

由于Django自带的User模型字段邮箱,所以我们需要对其扩展,最便捷的方式就是创建UserProfile的模型,如下所示。我们添加了org和phone两个字段。

from django.db import models
from django.contrib.auth.models import User
# Create your models here.


class UserProfile(models.Model):

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')

    org = models.CharField(
        'Organization', max_length=128, blank=True)

    phone = models.CharField(
        'phone', max_length=50, blank=True)

    mod_date = models.DateTimeField('Last modified', auto_now=True)

    class Meta:
        verbose_name = 'User Profile'

    def __str__(self):
        return "{}'s profile".format(self.user.__str__())

第三步 编写URLs和视图

我们需要编写2个URLs和对应视图来实现我们的功能。

myaccount/urls.py


from django.urls import path
from . import views

app_name = "myaccount"
urlpatterns = [
    path('profile/', views.profile, name='profile'),
    path('profile/update/', views.profile_update, name='profile_update'),
]

2个对应视图处理方法如下所示  myaccount/views.py

from django.shortcuts import render, get_object_or_404
from .models import UserProfile
from .forms import ProfileForm
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth.decorators import login_required


@login_required
def profile(request):
    user = request.user
    return render(request, 'account/profile.html', {'user': user})


@login_required
def profile_update(request):
    user = request.user
    user_profile = get_object_or_404(UserProfile, user=user)

    if request.method == "POST":
        form = ProfileForm(request.POST)
        # form表单验证提交数据的正确性
        if form.is_valid():
            # 获取筛选后的数据,参考django的form表单
            user.first_name = form.cleaned_data['first_name'] user.last_name = form.cleaned_data['last_name']
            user.save()

            user_profile.org = form.cleaned_data['org']
            user_profile.phone = form.cleaned_data['phone']
            user_profile.save()

            return HttpResponseRedirect(reverse('myaccount:profile'))
    else:
        default_data = {'first_name': user.first_name, 'last_name': user.last_name,
                        'org': user_profile.org, 'phone': user_profile.phone, }
        form = ProfileForm(default_data)

    return render(request, 'account/profile_update.html', {'form': form, 'user': user})

我们用户更新资料需要用到表单,所以我们把表单单独放在forms.py, 代码如下所示。我们创建了两个表单:一个是更新用户资料时使用,一个是重写用户登录表单。

myaccount/forms.py

from django import forms
from .models import UserProfile


class ProfileForm(forms.Form):

    first_name = forms.CharField(label='First Name', max_length=50, required=False)
    last_name = forms.CharField(label='Last Name', max_length=50, required=False)
    org = forms.CharField(label='Organization', max_length=50, required=False)
    phone = forms.CharField(label='phone', max_length=50, required=False)


class SignupForm(forms.Form):

    def signup(self, request, user):
        user_profile = UserProfile()
        user_profile.user = user
        user.save()
        user_profile.save()

为什么我们需要重写用户登录表单?因为django-allauth在用户注册只会创建User对象,不会创建与之关联的UserProfile对象,我们希望用户在注册时两个对象一起被创建,并存储到数据库中。这点非常重要。通过重写表单,你还可以很容易添加其它字段。

要告诉django-allauth使用我们自定义的登录表单,我们只需要在settings.py里加入一行。(settings.py文件中)

ACCOUNT_SIGNUP_FORM_CLASS = 'myaccount.forms.SignupForm'

第四步 编写模板

因为django-allauth默认会在templates/account/文件夹下寻找模板文件,为方便后续集中美化模板,我们也把模板文件放在这个文件夹中。

myaccount/templates/account/profile.html


{% block content %}
{% if user.is_authenticated %}
<a href="{% url 'myaccount:profile_update' %}">Update Profile</a> | <a href="{% url 'account_email' %}">Manage Email</a>  | <a href="{% url 'account_change_password' %}">Change Password</a> |
<a href="{% url 'account_logout' %}">Logout</a>
{% endif %}
<p>Welcome, {{ user.username }}.</p>


<h2>My Profile</h2>

<ul>
    <li>First Name: {{ user.first_name }} </li>
    <li>Last Name: {{ user.last_name }} </li>
    <li>Organization: {{ user.profile.org }} </li>
    <li>phone: {{ user.profile.phone }} </li>
</ul>


{% endblock %}

myaccount/templates/account/profile_update.html

{% block content %}
{% if user.is_authenticated %}
<a href="{% url 'myaccount:profile_update' %}">Update Profile</a> | <a href="{% url 'account_email' %}">Manage Email</a>  | <a href="{% url 'account_change_password' %}">Change Password</a> |
<a href="{% url 'account_logout' %}">Logout</a>
{% endif %}
<h2>Update My Profile</h2>

<div class="form-wrapper">
   <form method="post" action="" enctype="multipart/form-data">
      {% csrf_token %}
      {% for field in form %}
           <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
             <p class="help">{{ field.help_text|safe }}</p>
        {% endif %}
           </div>
        {% endfor %}
      <div class="button-wrapper submit">
         <input type="submit" value="Update" />
      </div>
   </form>
</div>


{% endblock %}

最后进行数据迁移然后启动项目查看效果

在你完成注册或登录后你可以看到个人信息页了。(自动跳转到accounts/profile/下面)

点击Update Profile, 你就可以更新个人资料了,如下图所示。

第六步 思考与改进

我们如何显示用户的邮箱是否验证过,并提醒他们去验证邮箱?Django实现这个也非常容易。我们只需要在模型models.py中新定义一个account_verified方法。

from django.db import models
from django.contrib.auth.models import User
from allauth.account.models import EmailAddress

# Create your models here.

class UserProfile(models.Model):

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')

    org = models.CharField(
        'Organization', max_length=128, blank=True)

    phone = models.CharField(
        'phone', max_length=50, blank=True)

    mod_date = models.DateTimeField('Last modified', auto_now=True)

    class Meta:
        verbose_name = 'User Profile'

    def __str__(self):
        return "{}'s profile".format(self.user.username)

    def account_verified(self):
        if self.user.is_authenticated:
            result = EmailAddress.objects.filter(email=self.user.email)
            if len(result):
                return result[0].verified
        return False

模板修改

<p>Welcome, {{ user.username }}.
    {% if not user.profile.account_verified %}
    (Unverified email.)
    {% endif %}
</p>

如果用户登录但邮箱未验证就会看到下面效果。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值