【问题标题】:Force User to Provide Profile Before Saving in Django Admin在 Django Admin 中保存之前强制用户提供配置文件
【发布时间】:2016-11-08 12:04:38
【问题描述】:

我试图强制用户在从 django 管理员保存之前提供配置文件。 这是我的个人资料模型

class UserProfile(models.Model):

    user=models.OneToOneField(AUTH_USER_MODEL,related_name='profile',primary_key=True)
    #other fields

    def get_user_info(user):
        return UserProfile.objects.get(user=user)
    @receiver(post_save, sender=AUTH_USER_MODEL)
    def create_profile_for_new_user(sender, created, instance, **kwargs):
        if created:
            profile = UserProfile(user=instance)
            profile.save()

我正在使用authtools,因此用户配置文件发件人是 AUTH_USER_MODEL。 如果我从管理员中添加新用户,即使他们没有提供或填写个人资料,他们也会被保存。 我想防止他们被保存,直到他们填写个人资料字段。 关于如何做到这一点的任何见解? 这是我的 admin.py

from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import PasswordResetForm
from django.utils.crypto import get_random_string

from authtools.admin import NamedUserAdmin
from authtools.forms import UserCreationForm

User = get_user_model()


class UserCreationForm(UserCreationForm):
    """
    A UserCreationForm with optional password inputs.
    """

    def __init__(self, *args, **kwargs):
        super(UserCreationForm, self).__init__(*args, **kwargs)
        self.fields['password1'].required = False
        self.fields['password2'].required = False
        # If one field gets autocompleted but not the other, our 'neither
        # password or both password' validation will be triggered.
        self.fields['password1'].widget.attrs['autocomplete'] = 'off'
        self.fields['password2'].widget.attrs['autocomplete'] = 'off'

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = super(UserCreationForm, self).clean_password2()
        if bool(password1) ^ bool(password2):
            raise forms.ValidationError("Fill out both fields")
        return password2


class UserAdmin(NamedUserAdmin):
    """
    A UserAdmin that sends a password-reset email when creating a new user,
    unless a password was entered.
    """
    inlines = [ UserProfileInline, ]
    add_form = UserCreationForm
    add_fieldsets = (
        (None, {
            'description': (
                "Enter the new user's name and email address and click save."
                " The user will be emailed a link allowing them to login to"
                " the site and set their password."
            ),
            'fields': ('email', 'name',),
        }),
        ('Password', {
            'description': "Optionally, you may set the user's password here.",
            'fields': ('password1', 'password2'),
            'classes': ('collapse', 'collapse-closed'),
        }),
    )

    def save_model(self, request, obj, form, change):
        if not change and not obj.has_usable_password():
            # Django's PasswordResetForm won't let us reset an unusable
            # password. We set it above super() so we don't have to save twice.
            obj.set_password(get_random_string())
            reset_password = True
        else:
            reset_password = True

        super(UserAdmin, self).save_model(request, obj, form, change)

        if reset_password:
            reset_form = PasswordResetForm({'email': obj.email})
            assert reset_form.is_valid()
            reset_form.save(
                subject_template_name='registration/account_creation_subject.txt',
                email_template_name='registration/account_creation_email.html',
            )


admin.site.unregister(User)
admin.site.register(User, UserAdmin)

【问题讨论】:

  • 我认为您的信号处理程序 (create_profile_for_new_user) 不应该在 UserProfile 下。
  • 嗨 Lauri Elias 1 我希望你能用你认为可行的方法发布这个:)
  • 改用信号,只要创建了新的身份验证用户,就让它创建身份验证配置文件。
  • @ChrisHawkers?有什么例子吗?

标签: django python-3.x django-models django-admin


【解决方案1】:

最好的方法是创建一个自定义中间件并检查登录用户是否填写了配置文件。如果没有,中间件会将用户重定向到一个视图,在那里他可以填写配置文件。

例子:

class ProfileMiddleware(MiddlewareMixin):
    def __init__(self, get_response=None):
        self.get_response = get_response

    def process_view(self, request, view_func, view_args, view_kwargs):
        if not request.user.profile:
            return HttpResponseRedirect(reverse('create-profile'))
        return None

尚未测试代码,但它应该可以帮助您入门。这是最干净的方式,它还会强制用户填写个人资料,否则他无法在网站上打开页面。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2020-07-17
    • 2010-09-18
    • 2015-12-31
    • 1970-01-01
    相关资源
    最近更新 更多