Django Allauth注册表单未保存自定义字段

时间:2020-08-15 20:57:39

标签: django django-allauth

我正在尝试做一些应该非常简单的事情:为注册添加一个字段并将其保存到我的用户对象中。我正在使用allauth,所以据我所知,应该这样做是通过修改allauth表单进行注册的。我已按照此处的说明进行操作:How to customize user profile when using django-allauth

这是我的forms.py的样子:

from allauth.account.forms import SignupForm
from django import forms

UNASSIGNED = 'NA'
CLIENT = 'CL'
USER_TYPE_CHOICES = (
    (UNASSIGNED, 'Unassigned'),
    (CLIENT, 'Client'),
)

class CustomSignupForm(SignupForm):
    user_type = forms.CharField( 
        widget=forms.Select(choices=USER_TYPE_CHOICES))
    def signup(self, request, user):
        user.user_type = self.cleaned_data['user_type']
        user.save
        return user

然后是我的自定义用户:

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=254, null=True, blank=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    
    UNASSIGNED = 'NA'
    CLIENT = 'CL'
    USER_TYPE_CHOICES = (
        (UNASSIGNED, 'Unassigned'),
        (CLIENT, 'Client'),
    )
    user_type = models.CharField(max_length=2,
                                      choices=USER_TYPE_CHOICES,
                                      default=UNASSIGNED)

    USERNAME_FIELD = 'email'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

    def get_absolute_url(self):
        return "/users/%i/" % (self.pk)

我知道添加到用户的字段可以正常工作,因为我可以在admin中看到它并在shell中访问它。表单正确呈现(我可以看到新字段的下拉列表。)问题是表单从不保存新的user_type字段,它始终显示为未分配状态。我将不胜感激有关故障排除的任何建议!我已经为此进行了一段时间的尝试,但没有发现具有相同问题的任何线程。

2 个答案:

答案 0 :(得分:0)

好的,在尝试了许多不同的发布解决方案之后,我发现了一些可行的方法。我不确定原因为何,所以如果有人收到我想解释一下,不过如果有人遇到类似问题而只想找到解决方案,我会在这里发布。

这是我的最终签到表格的样子:

class CustomSignupForm(SignupForm):
    user_type = forms.CharField( 
        widget=forms.Select(choices=USER_TYPE_CHOICES))

    class Meta:
        model = User

    def save(self, request):
        user = super(CustomSignupForm, self).save(request)
        user.user_type = self.cleaned_data['user_type']
        user.save()
        return user

(我认为)不推荐使用签名,而不是包括signup()函数,因此您似乎需要使用def save(self, request):。然后,您需要添加here.文档中提到的user = super(MyCustomSignupForm, self).save(request),这是我确实不了解的部分,但是确实存在。如果我弄清楚了,我会尽量记得再回来编辑它。

答案 1 :(得分:0)

当我开始使用Allauth时,我确实遇到了同样的挑战。主要区别在于,Allauth使用DefaultAccountAdapter 处理save_user逻辑。这就是super出现的地方。如this中所述,您在使用super时会调用Parent的save函数以及自己的save函数。在此处不调用super时,自定义字段永远不会传递到适配器中。尝试通过编写自己的自定义变量来发现DefaultaccountAdapter:

custom_adapter.py

const fs = require("fs");
const CryptoJS = require("crypto-js");

console.log(decode());

function decode() {
  // INIT
  const data = fs.readFileSync("./base64.txt", "utf-8"); // Base64 encoded string
  const encoded = data.toString();

  // PROCESS
  const encodedWord = CryptoJS.enc.Base64.parse(encoded); // encodedWord via Base64.parse()
  const decoded = CryptoJS.enc.Utf8.stringify(encodedWord); // decode encodedWord via Utf8.stringify() 
  return decoded;
}

请不要忘记将其放入您的设置:

class CustomAccountAdapter(DefaultAccountAdapter): 
     # your custom logic 
     return user #or whatever your user model is called 

祝您编程愉快!