【问题标题】:How to allow user to delete account in django allauth?如何允许用户删除 django allauth 中的帐户?
【发布时间】:2016-10-29 01:56:29
【问题描述】:

我正在尝试找出允许用户使用 django-allauth 删除或停用其帐户的最佳方法,并且我假设我需要将 is_active 字段设置为 False。

我下面的解决方案有几个问题: 1) 呈现的复选框字段 is_active 显示文本“指定是否应将此用户视为活动用户。取消选择此选项而不是删除帐户。”如何将此文本更改为“如果您确定要删除此帐户,请选中此框。”?

更新:刚刚意识到选中该框将 is_active 设置为 True,而取消选中该框将其设置为 False,所以也许我可能需要使用不同的字段来验证表单?

2) 如何在提交时注销用户?

forms.py:

class DeactivateUserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['is_active']

views.py:

login_required(login_url='/accounts/login/')
def deactivate_user_view(request):  
    pk = request.user.id
    user = User.objects.get(pk=pk)
    user_form = DeactivateUserForm(instance=user)
    if request.user.is_authenticated() and request.user.id == user.id:
        if request.method == "POST":
            user_form = DeactivateUserForm(request.POST, instance=user)
            if user_form.is_valid():
                deactivate_user = user_form.save(commit=False)
                user.is_active = False
                deactivate_user.save()
        return render(request, "account/userprofile_del.html", {
            "user_form": user_form,
        })
    else:
        raise PermissionDenied

userprofile_del.html:

<h2>Delete your account</h2>
<hr>
<form action="." method="POST" class="padding">{% csrf_token %}
    {{ user_form.as_p}}
    <button class="btn btn-primary" type="submit" name="action">{% trans "Confirm" %}</button>
</form>

渲染:

【问题讨论】:

  • 请注意,在某些司法管辖区(即至少所有欧盟),用户有权要求真正删除其帐户,而不仅仅是停用帐户。因此,根据您的服务,明确说明帐户是被停用还是删除,并提供执行真正删除的选项可能是明智之举。
  • 感谢您提出这个问题。我将不得不对用户的删除方法进行一些研究。

标签: python django django-allauth


【解决方案1】:

希望为停用和删除用户的视图提供潜在答案。

# forms.py

from django import forms

class UserDeactivateForm(forms.Form):
    """
    Simple form that provides a checkbox that signals deactivation.
    """
    deactivate = forms.BooleanField(required=True)


class UserDeleteForm(forms.Form):
    """
    Simple form that provides a checkbox that signals deletion.
    """
    delete = forms.BooleanField(required=True)
# views.py

# You could make this DRYer, but sometimes repeating yourself
# for explicitness makes sense.

from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.contrib.auth import logout
from django.shortcuts import redirect, render
from django.urls import reverse
from django.views.generic import View

from .forms import UserDeactivateForm, UserDeleteForm

class UserDeactivateView(LoginRequiredMixin, View):
    """
    Deactivates the currently signed-in user by setting is_active to False.
    """
    def get(self, request, *args, **kwargs):
        form = UserDeactivateForm()
        return render(request, 'users/user_deactivation.html', {'form': form})

    def post(self, request, *args, **kwargs):
        form = UserDeactivateForm(request.POST)
        # Form will be valid if checkbox is checked.
        if form.is_valid():
            # Make user inactive and save to database.
            request.user.is_active = False
            request.user.save()
            # Log user out.
            logout(request)
            # Give them a success message.
            messages.success(request, 'Account successfully deactivated')
            # Redirect to home page.
            return redirect(reverse('home'))
        return render(request, 'users/user_deactivation.html', {'form': form})


class UserDeleteView(LoginRequiredMixin, View):
    """
    Deletes the currently signed-in user and all associated data.
    """
    def get(self, request, *args, **kwargs):
        form = UserDeleteForm()
        return render(request, 'users/user_deletion.html', {'form': form})

    def post(self, request, *args, **kwargs):
        form = UserDeleteForm(request.POST)
        # Form will be valid if checkbox is checked.
        if form.is_valid():
            user = request.user
            # Logout before we delete. This will make request.user
            # unavailable (or actually, it points to AnonymousUser).
            logout(request)
            # Delete user (and any associated ForeignKeys, according to
            # on_delete parameters).
            user.delete()
            messages.success(request, 'Account successfully deleted')
            return redirect(reverse('home'))
        return render(request, 'users/user_deletion.html', {'form': form})

然后您需要为每个模板和 URL 路由创建模板,但这些应该非常简单。

【讨论】:

    【解决方案2】:

    对于问题 1,覆盖该字段的帮助文本属性;您可以在 ModelForm 的 init 方法中执行此操作。

    class DeactivateUserForm(forms.ModelForm):
        class Meta:
            model = User
            fields = ['is_active']
    
        def __init__(self, *args, **kwargs):
            super(DeactivateUserForm, self).__init__(*args, **kwargs)
            self.fields['is_active'].help_text = "Check this box if you are sure you want to delete this account."
    
        def clean_is_active(self):  
            # Reverses true/false for your form prior to validation
            #
            # You can also raise a ValidationError here if you receive 
            # a value you don't want, to prevent the form's is_valid 
            # method from return true if, say, the user hasn't chosen 
            # to deactivate their account
            is_active = not(self.cleaned_data["is_active"])
            return is_active
    

    对于问题 2,您可能需要禁用 allauth 中介注销页面。在您的设置中:

    ACCOUNT_LOGOUT_ON_GET = True
    

    并在您的视图逻辑中重定向到注销页面。

    from django.shortcuts import HttpResponseRedirect
    from django.core.urlresolvers import reverse_lazy
    
        # ... in your view
        if user_form.is_valid():
            deactivate_user = user_form.save(commit=False)
            user.is_active = False
            deactivate_user.save()
            return HttpResponseRedirect(reverse_lazy('account_logout')) 
    

    这将重定向到注销 url,然后它将通过 ACCOUNT_LOGOUT_REDIRECT_URL 将用户转发到您在设置中设置的 url。您的用户帐户现已停用,并且已注销。

    【讨论】:

    • 您对 #2 的解决方案有效,但我刚刚意识到问题 #1,选中该框将 is_active 设置为 True,而取消选中该框将其设置为 False,因此也许我可能需要使用不同的复选框如果 help.text 显示“选中此框以删除”,则验证表单的字段?我不想让 help.text 显示“取消选中此框以确认删除您的帐户”
    • 自定义清理方法允许您反转复选框选择。将在上面添加:)
    猜你喜欢
    • 2018-01-28
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 2021-08-18
    • 1970-01-01
    • 2011-01-19
    相关资源
    最近更新 更多