在Django注册表单中添加额外字段

6

我有一个名为“Organization”的模型,我已将其设置为用户配置文件,并希望在注册页面上显示来自“Organization”模型的字段。如何使用django-registration实现此目标?

# models.py
class Organization(models.Model):
    user = models.ForeignKey(User, unique=True)
    logo = models.ImageField(upload_to='organizations')
    name = models.CharField(max_length=100, null=True, unique=True)

    # more fields below etc.

# settings.py
AUTH_PROFILE_MODULE = 'volunteering.organization'
4个回答

6
这个最简单的方法已经经过测试,适用于django-registration 0.8:
在您的项目中某处,例如组织应用程序的forms.py文件中。
from registration.forms import RegistrationForm
from django.forms import ModelForm
from models import Organization

class OrganizationForm(forms.ModelForm):
    class Meta:
        model = Organization

RegistrationForm.base_fields.update(OrganizationForm.base_fields)

class CustomRegistrationForm(RegistrationForm):
    def save(self, profile_callback=None):
        user = super(CustomRegistrationForm, self).save(profile_callback=None)
        org, c = Organization.objects.get_or_create(user=user, \
            logo=self.cleaned_data['logo'], \
            name=self.cleaned_data['name'])

然后在您的根urlconf [但在包含registration.urls的正则表达式模式之上,并假设该模式是r'^accounts/']中添加:

from organization.forms import CustomRegistrationForm

urlpatterns += patterns('',
    (r'^accounts/register/$', 'registration.views.register',    {'form_class':CustomRegistrationForm}),
)

显然,你也可以创建自定义后端,但我个人认为这种方法更加简单易行。

我一直收到这个错误:register()至少需要2个非关键字参数(但只提供了1个)。 - anc1revv
这是由于django-registration的不同版本造成的。我相信他在0.8版本中进行了重写。 - Cianan Sims

2
最好的方法是在您拥有组织的应用程序中创建一个文件(比如"forms.py"),并执行以下操作:
from registration.forms import RegistrationForm
from forms import *
from models import Organization

class RegistrationFormWithOrganization(RegistrationForm):
    organization_logo = field.ImageField()
    organization_name = field.CharField()

def save(self, profile_callback = None):
    Organization.objects.get_or_create(user = self.cleaned_data['user'],
                                       logo = self.cleaned_data['organization_logo'],
                                       name = self.cleaned_data['organization_name'])

    super(RegistrationFormWithOrganization, self).save(self, profile_callback)

然后在您的基本URL中,覆盖现有的注册URL,并将此表单添加为要使用的表单:

 form organization.forms import RegistrationFormWithOrganization

 url('^/registration/register$', 'registration.views.register', 
     {'form_class': RegistrationFormWithOrganization}),
 url('^/registration/', include('registration.urls')),

请记住,Django将使用与正则表达式匹配的第一个URL,因此将匹配您的调用而不是django-registration的调用。它还会告诉registration使用您的表单而不是它自己的表单。我在这里跳过了很多验证(可能还有用户对象的派生...如果是这样,请阅读registration的源代码以查看它来自哪里),但这绝对是在页面上轻松添加一些内容的正确方法。请保留HTML标签。

这样做是行不通的,因为(a)RegistrationForm没有一个user字段,所以self.cleaned_data['user']会抛出一个KeyError异常;(b)你需要一个User对象来创建一个Organization对象,而且在调用RegistrationForm.save返回新创建的user对象之前,你无法得到它。请参见我的答案,了解另一种解决方案。 - Simon Kagwi
@SimonKagwi 我使用了你的答案,但是我一直收到这个错误:TypeError at /accounts/register/ register() 至少需要 2 个非关键字参数(已给出 1 个)。 - anc1revv

1
请按照以下方式修改代码,然后再试一次。
urlpatterns += patterns('',
(r'^accounts/register/$', 'registration.views.register',    {'form_class':CustomRegistrationForm,'backend': 'registration.backends.default.DefaultBackend'}),

)


0
“以前,在注册期间收集数据的表单需要实现一个save()方法来创建新用户账户。但现在不再需要这样做了,创建账户由后端处理,因此任何自定义逻辑都应该移动到自定义后端或通过连接在注册过程中发送的信号的监听器来处理。”
“详情:”
“更多信息可以在这里找到。”

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