2016-11-08 23 views
0

我試圖強制用戶在從django管理員保存配置文件之前提供配置文件。 這裏是我的剖面模型使用authtools強制用戶在保存到Django Admin之前提供配置文件

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() 

是多麼的用戶配置文件發送者是AUTH_USER_MODEL。 如果我從admin內添加新用戶,即使他們沒有提供或填寫個人資料,也會保存它們。 我想阻止他們保存,直到他們填寫配置文件字段。 關於如何做到這一點的任何見解? 這裏是我的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) 
+0

我不認爲你的信號處理程序(create_profile_for_new_user)應該在UserProfile下。 –

+0

嗨勞裏埃利亞斯1我寧願如果你發佈這個與你認爲的工作:) – Joshua

+0

看起來使用信號,而不是創建一個新的auth用戶創建一個auth配置文件。 –

回答

0

要做到這一點,最好的方法是創建一個自定義的中間件和檢查,如果登錄用戶已經填寫了個人資料。如果沒有,中間件會將用戶重定向到一個視圖,在這裏他可以填寫配置文件。

例子:

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 

沒有測試的代碼,但它應該讓你開始。這是這樣做的最乾淨的方式,它也會強制用戶填寫個人資料,否則他無法在網站上打開一個頁面。

希望這會有所幫助。

相關問題