使用Django-allauth在用户注册时创建用户和用户资料。

3

我正在使用django-allauth来处理账户、登录、注销和注册,但是我希望在创建用户时必须创建一个profile,我使用了模型UserProfile,如代码所示。问题是当我创建自定义的注册表单后,现在它只会创建一个具有[用户名、电子邮件、名字、姓氏、密码]的用户,但不会创建UserProfile。我的三个问题如下:

  1. 如何在注册时创建User和UserProfile?
  2. 如何为django-allauth提供的表单添加样式,例如/accounts/login/?
  3. 如何修改用户登录后重定向到/profiles/,而不是/accounts/profiles/,或是从REST原则来看,是否更好将其设置为/accounts/profiles/?如果是,那么是否可以修改profiles应用程序以使用django-allauth视图?

我的自定义注册表单:

# django_project/profiles/forms.py
from django import forms
from allauth.account.forms import SignupForm
 
 
class CustomSignupForm(SignupForm):
    first_name = forms.CharField(max_length=30, label='First Name')
    last_name = forms.CharField(max_length=30, label='Last Name')
    bio = forms.CharField(max_length=255, label='Bio')
    def save(self, request):
        user = super(CustomSignupForm, self).save(request)
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.bio = self.cleaned_data['bio']
        user.save()
        return user

设置:

# django_project/django_project/settings.py
ACCOUNT_FORMS = {
    'signup': 'profiles.forms.CustomSignupForm',
}

主要的URL模式:

# django_project/django_project/urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('profiles/', include('profiles.urls')),
    path('accounts/', include('allauth.urls')),
] 

个人资料应用中的URL模式:

# django_project/profiles/urls.py
app_name = 'profiles'
urlpatterns = [
    path('<str:user>/', ProfileView.as_view(), name='profile-detail'),
]

这是我的简介视图(ProfileView):

class ProfileView(LoginRequiredMixin, View):
    def get(self, request, user, *args, **kwargs):
        profile = UserProfile.objects.get(user=user)
        my_user = profile.user
        context = {
            'user': my_user,
            'profile': profile,
        }
        return render(request, 'profile/profile.html', context)

我有一个与Django用户模型不同的用户配置文件:

User = settings.AUTH_USER_MODEL

class UserProfile(models.Model):
    user = models.OneToOneField(User, primary_key=True, verbose_name='user',
                                related_name='profile', on_delete=models.CASCADE)
    first_name = models.CharField(max_length=30, blank=True, null=True)
    last_name = models.CharField(max_length=30, blank=True, null=True)
    email = models.CharField(max_length=30, blank=True, null=True)
    bio = models.TextField(max_length=500, blank=True, null=True)

用户创建的信号:

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()
2个回答

3

如何在注册时创建用户和用户资料?

您可以同时保存CustomSignupForm并创建一个UserProfile

def save(self, request):
    user = super(CustomSignupForm, self).save(request)
    user.first_name = self.cleaned_data['first_name']
    user.last_name = self.cleaned_data['last_name']
    user.bio = self.cleaned_data['bio']
    user.save()
    
    # Create your user profile
    UserProfile.objects.create(user=user, first_name=self.cleaned_data['first_name'], last_name=self.cleaned_data['last_name'], email=self.cleaned_data['email'], bio=self.cleaned_data['bio'])

另一种优雅的方法是使用Django信号来在事件发生后执行某些操作,例如用户创建

signals.py

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import UserProfile

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        first_name = instance.first_name
        last_name = instance.last_name
        email = instance.email
        # The bio field is not set because the User instance has not bio attribute by default.
        # But you can still update this attribute with the profile detail form.
        UserProfile.objects.create(user=instance, first_name=first_name, last_name=last_name, email=email)

如果您想在每次更新用户时更新配置文件,请删除信号主体中的if createdapps.py
class AppNameConfig(AppConfig):
    
    # some code here

    # import your signal in the ready function
    def ready(self):
        import app_name.signals

忘记添加信号了,请你检查我编辑后的问题? - Sachihiro
我会更新我的答案,添加一个信号示例,在创建新用户后创建个人资料。 - Rvector

1

如何在注册时创建用户和用户资料?

 class CustomSignupForm(SignupForm):
    first_name = forms.CharField(max_length=30, label='First Name')
    last_name = forms.CharField(max_length=30, label='Last Name')
    bio = forms.CharField(max_length=255, label='Bio')
    def save(self, request):
        # create user the create profile
        user = super(CustomSignupForm, self).save(request)
        ### now save your profile 
        profile = UserProfile.objects.get_or_create(user=user)
        profile.first_name = self.cleaned_data['first_name']
        profile.last_name = self.cleaned_data['last_name']
        profile.bio = self.cleaned_data['bio']
        profile.save()
        return user

如何为django-allauth提供的表单添加样式,例如:

在您的模板中创建一个名为/account/login.html的新目录,并在其中呈现您的表单,然后按照以下方式添加样式

这可以通过多种方式完成

  1. 使用https://pypi.org/project/django-bootstrap4/
  2. https://pypi.org/project/django-widget-tweaks/
  3. 手动呈现字段https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html

如何修改用户登录后重定向到/profiles/而不是/accounts/profiles/,或者从REST原则的角度来看,是否最好将其设置为/accounts/profiles/?如果是,则是否可以修改profiles应用程序以使用django-allauth视图?

前往您的设置文件并添加以下内容

LOGIN_REDIRECT_URL = "/profiles"

您可以在此处查看更多设置 https://django-allauth.readthedocs.io/en/latest/configuration.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接