首页 文章

使用django添加用户时自动生成用户名

提问于
浏览
1

我正在尝试将用户名保存为名字,同时从django admin添加用户 . 目前,它在用户名字段中保存了 None ,因为我在自定义模型中排除了 username .

admin.py--

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from .models import UserProfile
from .forms import SignUpForm

class ProfileInline(admin.StackedInline):
    model = UserProfile
    can_delete = False
    verbose_name_plural = 'Profile'
    fk_name = 'user'


class CustomUserAdmin(UserAdmin):
    inlines = (ProfileInline, )
    list_display = ('email', 'first_name', 'last_name', 'is_staff')
    list_select_related = ( 'profile', )

    exclude = ('username',)

    fieldsets = (
        ('Personal information', {'fields': ('first_name', 'last_name', 'email', 'password')}),
        ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
        ('Important dates', {'fields': ('last_login', 'date_joined')}),
    )

    add_fieldsets = (
        ('None', {
            'classes': ('wide',),
            'fields': ('first_name','last_name', 'email', 'password1', 'password2')}
        ),
    )


    def get_inline_instances(self, request, obj=None):
        if not obj:
            return list()
        return super(CustomUserAdmin, self).get_inline_instances(request, obj)


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

forms.py

from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Field
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteField
from phonenumber_field.formfields  import PhoneNumberField
from . import models
from captcha.fields import ReCaptchaField


class SignUpForm(forms.Form):
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=30)
    phone_number = PhoneNumberField(label=_("Phone (Please state your country code eg. +44)"))
    organisation = forms.CharField(max_length=50)
    email = forms.EmailField()
    password1 = forms.CharField(max_length=20)
    password2 = forms.CharField(max_length=20)
    captcha = ReCaptchaField(attrs={'theme' : 'clean'})



    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        """
        profile, created = models.UserProfile.objects.get_or_create(user=user)
        profile.phone_number = self.cleaned_data['phone_number']
        profile.organisation = self.cleaned_data['organisation']
        profile.save()
        user.save()
        """
        up = user.profile
        up.phone_number = self.cleaned_data['phone_number']
        up.organisation = self.cleaned_data['organisation']
        user.save()
        up.save()

models.py -

from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from easy_thumbnails.fields import ThumbnailerImageField
from ciasroot.settings import THUMBNAILER_SIZES, UPLOAD_PATH
from ciasroot.constants import GENDERS, LANGUAGES
from ciasroot.util import HashedPk
from phonenumber_field.modelfields import PhoneNumberField
import math, decimal, datetime, os
import uuid

    def random_username(sender, instance, **kwargs):
        if not instance.username:
            instance.username = uuid.uuid4().hex[:30]
            models.signals.pre_save.connect(random_username, sender=User)

class UserProfile(models.Model, HashedPk):
    user = models.OneToOneField(User, unique=True, related_name ='profile')
    job_title = models.CharField(max_length=128, blank=True, null=False, default="")
    website = models.URLField(max_length=255, blank=True, null=True)
    organisation = models.CharField(max_length=50, blank=True, null=True, default="")
    phone_number = PhoneNumberField( blank=True, null=True)

    def __str__(self):
        return self.user.get_full_name()

    def save(self, *args, **kwargs):
        super(UserProfile, self).save(*args, **kwargs)
        LookupSuggest.add("job_title", self.job_title)

如何将用户名作为名字插入并生成自定义字段,即“必填”电子邮件 . 现在password1和password2字段是必填字段 .

任何帮助/链接都非常感谢 .

2 回答

  • 0

    您可以将用户名定义为只读字段 .

    def user_first_name(obj):
        return obj.first_name
    
    user_firstname.short_description = 'Firstname'
    
    class CustomUserAdmin(UserAdmin):
        readonly_fields = ('user_firstname')
        inlines = (ProfileInline, )
        list_display = ('email', 'user_first_name', 'last_name', 'is_staff')
        list_select_related = ( 'profile', )
    
        exclude = ('username',)
        ...
    

    有关验证电子邮件的第二个问题,请为 CustomUserAdmin 定义表单 .

    class CustomUserAdmin(UserAdmin):
        ...
        form = CustomUserAdminForm 
    
    class CustomUserAdminForm(forms.ModelForm):
        def clean_email(self):
           if not self.cleaned_data['email']:
               raise forms.ValidationError("Email is required")
    
           return self.cleaned_data['email']
    

    要么:

    class CustomUserAdminForm(forms.ModelForm):
        email = forms.EmailField(required=True)
    
  • 0

    要使用用户的名字自动填充用户名,您应该使用signal - 将以下内容添加到已定义UserProfile的 models.py 中:

    def set_username(sender, instance, **kwargs):
        if not instance.username:
            instance.username = instance.first_name
    models.signals.pre_save.connect(set_username, sender=User)
    

    这样做的问题是,如果您有两个具有相同名字的用户,则用户名将不是唯一的,因此您将从数据库中获得完整性错误 . 您可以检查唯一性并附加一个数字,直到获得唯一值:

    def set_username(sender, instance, **kwargs):
        if not instance.username:
            username = instance.first_name
            counter = 1
            while User.objects.filter(username=username):
                username = instance.first_name + str(counter)
                counter += 1
            instance.username = username
    models.signals.pre_save.connect(set_username, sender=User)
    

    或者,如果您根本不使用用户名,则可以使用uuid将其设置为随机唯一值:

    import uuid
    
    def random_username(sender, instance, **kwargs):
        if not instance.username:
            instance.username = uuid.uuid4().hex[:30]
    models.signals.pre_save.connect(random_username, sender=User)
    

    如果您打算使用电子邮件登录而不是用户名,您还需要强制执行电子邮件唯一性,将电子邮件添加到管理员用户创建表单 - 这应该可以满足您的需求:https://gist.github.com/gregplaysguitar/1184995

相关问题