Django用户未在管理网站

时间:2017-11-16 13:26:27

标签: python django

我通过使用内置注册激活功能发送令牌激活电子邮件来注册用户。注册表单是UserCreationForm的子类,用于为电子邮件 date_of_birth 验证添加额外字段。我的代码如下:

forms.py:

class UserRegisterForm(UserCreationForm):

date_of_birth = forms.DateField(widget=forms.SelectDateWidget(years=range(2017, 1900, -1)))
email = forms.EmailField(required=True)

def clean_username(self):
    username = self.cleaned_data.get('username')
    if User.objects.filter(username__iexact=username).exists():
        raise forms.ValidationError('Username already exists')
    return username

def clean_date_of_birth(self):
    '''
    Only accept users aged 13 and above
    '''
    userAge = 13
    dob = self.cleaned_data.get('date_of_birth')
    today = date.today()
    if (dob.year + userAge, dob.month, dob.day) > (today.year, today.month, today.day):
        raise forms.ValidationError('Users must be aged {} years old or above.'.format(userAge))
    return dob

def clean_email(self):
    email = self.cleaned_data.get('email')
    if User.objects.filter(email__iexact=email).exists():
        raise forms.ValidationError('A user has already registered using this email')
    return email

def clean_password2(self):
    '''
    we must ensure that both passwords are identical
    '''
    password1 = self.cleaned_data.get('password1')
    password2 = self.cleaned_data.get('password2')
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError('Passwords must match')
    return password2

class Meta:
    model = User
    fields = ['username', 'email', 'date_of_birth', 'password1', 'password2']

views.py:

def register(request):
   if request.method == 'POST':
       form = UserRegisterForm(request.POST)
       if form.is_valid():
          email = form.cleaned_data.get('email')
          date_of_birth = form.cleaned_data.get('date_of_birth')
          new_user = form.save(commit=False)
          new_user.is_active = False
          new_user.save()
          current_site = get_current_site(request)
          message = render_to_string('email_activation_link.html', {
            'new_user':new_user,
            'domain':current_site.domain,
            'uid': urlsafe_base64_encode(force_bytes(new_user.pk)),
            'token': account_activation_token.make_token(new_user),
          })
          mail_subject = 'Activate your Frac account.'
          to_email = EmailMessage(mail_subject, message, to=[email])
          to_email.send()
        return render(request, 'register_confirm.html', {'form': form})
   else:
      form = UserRegisterForm()

   return render(request, 'register.html', {'form': form})


def activate(request, uidb64, token):
   try:
       uid = force_text(urlsafe_base64_decode(uidb64))
       new_user = User.objects.get(pk=uid)
   except(TypeError, ValueError, OverflowError, User.DoesNotExist):
       new_user = None
   if new_user is not None and account_activation_token.check_token(new_user, token):
      new_user.is_active = True
      new_user.save()
      return render(request, 'register_complete.html', {})
   else:
      return render(request, 'registration_incomplete.html', {})

models.py:

class UserProfile(models.Model):
   '''
   Extends the Django User model
   '''
   user = models.OneToOneField(settings.AUTH_USER_MODEL,
                            related_name='profile')
   email = models.EmailField(blank=True)
   date_of_birth = models.DateField(blank=True, null=True)
   profile_photo = models.ImageField(blank=True)
   following = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                    blank=True,
                                    related_name='followed_by')

   def __str__(self):
       return 'Followers({});Following({})'.format(self.user.followed_by.all().count(),self.get_following().count())

def post_save_user_receiver(sender, instance, created, *args, **kwargs):
   '''
   Django signals to automatically create
   a user profile when a user object is created
   '''
   if created:
       new_profile, is_created = UserProfile.objects.get_or_create(user=instance)

post_save.connect(post_save_user_receiver, sender=settings.AUTH_USER_MODEL)

admin.py:

from django.contrib import admin

from .models import UserProfile

class ProfileAdmin(admin.ModelAdmin):
    list_display = ['user', 'id', 'date_of_birth', 'profile_photo', '__str__']


admin.site.register(UserProfile, ProfileAdmin)

新用户已正确注册。但是,只有用户名电子邮件字段会显示在Django管理网站的“用户”部分中。我无法弄清楚为什么 date_of_birth 字段没有为新注册的用户显示。

2 个答案:

答案 0 :(得分:1)

您尚未扩展用户模型,您已添加了相关的用户个人资料。您不会在任何地方执行任何操作来实际创建此用户配置文件的实例,或使用表单中的数据填充它们;您可以在视图中获取DOB和电子邮件值,然后继续忽略它们。

您需要使用这些值创建配置文件:

   if form.is_valid():
      new_user = form.save(commit=False)
      new_user.is_active = False
      new_user.save()
      email = form.cleaned_data.get('email')
      date_of_birth = form.cleaned_data.get('date_of_birth')
      UserProfile.objects.create(user=new_user, email=email, date_of_birth=date_of_birth)

答案 1 :(得分:1)

date_of_birth字段属于UserProfile模型,因此您不应将其包含在用户表单fields中。

class UserRegisterForm(UserCreationForm):
    ...

    class Meta:
        model = User
        fields = ['username', 'email']

在您的视图中,您可以获取信号创建的个人资料,并设置出生日期,您可以从已清理的数据中获取该日期。

   if form.is_valid():
      email = form.cleaned_data.get('email')
      date_of_birth = form.cleaned_data.get('date_of_birth')
      new_user = form.save(commit=False)
      new_user.is_active = False
      new_user.save()
      profile = new_user.profile
      profile.date_of_birth=date_of_birth
      profile.save()