Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用django allauth时如何自定义用户配置文件_Django_Profile_Django Allauth - Fatal编程技术网

使用django allauth时如何自定义用户配置文件

使用django allauth时如何自定义用户配置文件,django,profile,django-allauth,Django,Profile,Django Allauth,我有一个django项目和django allauth应用程序。我需要在注册时从用户那里收集额外的数据。我遇到了一个类似的问题,但不幸的是,没有人回答配置文件定制部分 Per: ACCOUNT\u SIGNUP\u FORM\u CLASS(=None) 指向自定义表单类(例如,'myapp.forms.SignupForm')的字符串,在注册过程中用于请求用户进行其他输入(例如,时事通讯注册、出生日期)。此类应实现一个'save'方法,接受新注册的用户作为其唯一参数 我是django的新手,正

我有一个django项目和django allauth应用程序。我需要在注册时从用户那里收集额外的数据。我遇到了一个类似的问题,但不幸的是,没有人回答配置文件定制部分

Per:

ACCOUNT\u SIGNUP\u FORM\u CLASS
(=
None
) 指向自定义表单类(例如,
'myapp.forms.SignupForm'
)的字符串,在注册过程中用于请求用户进行其他输入(例如,时事通讯注册、出生日期)。此类应实现一个
'save'
方法,接受新注册的用户作为其唯一参数


我是django的新手,正在努力解决这个问题。有人能提供这样一个自定义表单类的示例吗?我是否需要添加一个模型类以及一个指向用户对象的链接,如?

创建一个配置文件模型,其中用户为OneToOneField

class Profile(models.Model):
    user = models.OneToOneField(User, verbose_name=_('user'), related_name='profiles')
    first_name=models.CharField(_("First Name"), max_length=150)
    last_name=models.CharField(_("Last Name"), max_length=150)
    mugshot = ImageField(_('mugshot'), upload_to = upload_to, blank=True)
    phone= models.CharField(_("Phone Number"), max_length=100)
    security_question = models.ForeignKey(SecurityQuestion, related_name='security_question')
    answer=models.CharField(_("Answer"), max_length=200)
    recovery_number= models.CharField(_("Recovery Mobile Number"), max_length=100)
    city=models.ForeignKey(City,related_name='city', blank=True, null=True, help_text=_('Select your City'))
    location=models.ForeignKey(Country,related_name='location', blank=True, null=True, help_text=_('Select your Location'))

假设您想在注册过程中询问用户的名字/姓氏。您需要以自己的形式放置这些字段,如下所示:

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()
然后,在设置中指向此表单:

ACCOUNT_SIGNUP_FORM_CLASS = 'yourproject.yourapp.forms.SignupForm'

仅此而已。

使用pennersr建议的解决方案,我收到了一条弃用警告:

DeprecationWarning: The custom signup form must offer a def signup(self, request, user) method DeprecationWarning)
这是因为save方法已被弃用,取而代之的是def signup(请求,用户)方法

所以要解决这个问题,示例的代码应该如下所示:

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

users/forms.py
中,您将:

from django.contrib.auth import get_user_model
class SignupForm(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ['first_name', 'last_name']
    def save(self, user):
        user.save()
在settings.py中,您可以放置:

ACCOUNT_SIGNUP_FORM_CLASS = 'users.forms.SignupForm'

这样,您就不会因为多重用户模型字段定义而打破枯燥的原则

以下是结合其他几个答案对我有效的方法(没有一个答案是100%完整和干燥的)

yourapp/forms.py
中:

from django.contrib.auth import get_user_model
from django import forms

class SignupForm(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ['first_name', 'last_name']

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()
ACCOUNT_SIGNUP_FORM_CLASS = 'yourapp.forms.SignupForm'
settings.py
中:

from django.contrib.auth import get_user_model
from django import forms

class SignupForm(forms.ModelForm):
    class Meta:
        model = get_user_model()
        fields = ['first_name', 'last_name']

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()
ACCOUNT_SIGNUP_FORM_CLASS = 'yourapp.forms.SignupForm'

通过这种方式,它使用模型表单使其干燥,并使用新的
def注册
。我试着把
'myproject.myapp.forms.SignupForm'
放在上面,但不知怎么的,结果出现了一个错误。

@shryas:下面的解决方案可能不是最干净的,但它可以工作。如果你有任何进一步清理的建议,请告诉我

要添加不属于默认用户配置文件的信息,请首先在yourapp/models.py中创建一个模型。阅读一般django文档了解更多信息,但基本上:

from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='profile')
    organisation = models.CharField(organisation, max_length=100, blank=True)
然后在yourapp/forms.py中创建一个表单:

from django import forms

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label='Voornaam')
    last_name = forms.CharField(max_length=30, label='Achternaam')
    organisation = forms.CharField(max_length=20, label='organisation')

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        # Replace 'profile' below with the related_name on the OneToOneField linking back to the User model
        up = user.profile
        up.organisation = self.cleaned_data['organisation']
        user.save()
        up.save()

我尝试了很多不同的教程,但都遗漏了一些东西,重复了不必要的代码或做了一些奇怪的事情,bellow遵循我的解决方案,加入了我找到的所有选项,它正在工作,我已经把它投入生产,但它仍然不能说服我,因为我希望在我附加到用户创建的函数中接收名字和姓氏,以避免在表单中创建配置文件,但我不能,顺便说一句,我认为这会对您有所帮助

Models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField(max_length=500, blank=True)
    nationality = models.CharField(max_length=2, choices=COUNTRIES)
    gender = models.CharField(max_length=1, choices=GENDERS)

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


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

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()
Forms.py

class SignupForm(forms.ModelForm):
    first_name = forms.CharField(max_length=100)
    last_name = forms.CharField(max_length=100)

    class Meta:
        model = Profile
        fields = ('first_name', 'last_name', 'nationality', 'gender')

    def signup(self, request, user):
        # Save your user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

        user.profile.nationality = self.cleaned_data['nationality']
        user.profile.gender = self.cleaned_data['gender']
        user.profile.save()
设置.py

ACCOUNT_SIGNUP_FORM_CLASS = 'apps.profile.forms.SignupForm'

就是这样。(:

谢谢,但我不认为这是所需要的全部。我的问题特别涉及allauth应用程序。谢谢。听到原作者的消息总是很好:)。我是否需要创建一个额外的类来存储这些信息,还是allauth会自动处理这些信息?这实际上取决于您所询问的信息。无论如何,这都超出了allauth的范围。如果您像上面的示例中那样询问名字/姓氏,那么您不需要额外的模型,可以直接将内容放入用户模型中。如果您想询问用户的生日、他最喜欢的颜色或其他信息,那么您需要为此设置自己的配置文件模型。请在这里看看如何做到这一点:这正是我所寻找的-一个额外的领域喜欢最喜欢的颜色。如果我对最喜欢的颜色感兴趣,我相信我应该创建一个新的UserProfile类,然后将用户用作一对一字段,将最喜欢的颜色用作附加字段。在这种情况下,我仍然可以使用您在上面声明的一种注册表单(使用最喜欢的颜色)并将ACCOUNT\u SIGNUP\u FORM\u类连接到它,还是需要创建表单并用自己的代码保存数据?当然,ACCOUNT\u SIGNUP\u FORM\u类机制仍然可以使用。您只需确保save()方法得到了正确的实现,以便最喜欢的颜色存储在您想要的任何模型中。@pennersr-在第一次社交登录之后,我如何才能将此
帐户注册表单类
用于收集和保存自定义用户模型字段?另外,在pypi中没有上载git:中的更改所使用的自定义用户模型。配置文件字段没有默认值,也不允许null,因此您的
create\u user\u Profile
信号设计失败。其次,您可以根据创建的
将此信号减少为一个信号,尤其是在干巴巴地说话时。第三,通过在视图中调用user.save()实现配置文件保存,然后使用实际数据再次保存配置文件。@Melvyn不应该使用方括号而不是
fields=[…]
括号来保存配置文件吗?可以,但不必如此。它仅用于只读检查模型上的字段是否应为表单的一部分。所以它可以是一个列表、元组或集合或其任何衍生物。由于元组是不可变的,所以使用元组和防止意外突变更有意义。从性能角度来看,这些集合实际上太小,无法产生任何影响。一旦收集时间过长,切换到
exclude
可能是有意义的。@Pennser的答案现在已被编辑为使用
signup
而不是
save
。这正是我在运行Wagtail CMS的Django 2.0应用程序中使用的。用于常规注册,但在Social Auth中似乎不太适用?我如何将此额外字段添加到Wagtail中用户的管理页面?使用“yourapp.forms.SignupForm”而不是“myproject.myapp.forms.SignupForm”也适用于我