无法分配“”:“”必须是一个“”实例

Cannot assign "": "" must be a '' instance

我正在尝试在 UserModel 中创建一个注册密钥,其中注册表单中的密钥字段是另一个名为 RegistrationKey 的模型的外键。我早些时候就这个主题发表了两篇文章,但没有成功,但是我的代码中发生了一些变化,这使得之前的文章变得无关紧要。在表单字段中,密钥字段是一个 CharField,因为出于安全考虑,我无法为用户显示密钥。

这是之前的两个帖子: Save user input which is a string as object in db , Textinput with ModelChoiceField

这是我的两个模型。

class RegistrationKey(models.Model):
    key = models.CharField(max_length=30)

    def __str__(self):
        return self.key


class User(AbstractUser):
    key = models.ForeignKey(RegistrationKey, on_delete=models.CASCADE, null=True, blank=True)

自从我最近的帖子以来,我创建了一个基于 class 的视图,如下所示:

class RegisterPage(CreateView):
    form_class = MyUserCreationForm


  def form_valid(self, form):
        key = form.cleaned_data['key']
        try:
            keyobject = RegistrationKey.objects.get(key=key)
            form.instance.key = keyobject
            return super().form_valid(form)
        except RegistrationKey.DoesNotExist:
            form.add_error('key', 'error')
            return super().form_invalid(form)

当我尝试传入作为 RegistrationKey 模型中对象的值 Admin 时,出现以下错误: '无法分配“'Admin'”:“User.key”必须是“RegistrationKey”实例。 我不知道如何解决这个问题,用户输入的这个字符串如何分配给数据库?

编辑 这是我的表格

class MyUserCreationForm(UserCreationForm):
    key = forms.CharField(widget=forms.TextInput(attrs={'class':'form-control', 'placeholder':'Key'}), label='')
    email = forms.EmailField(widget=forms.EmailInput(attrs={'class':'form-control', 'placeholder':'Email'}), label='')



    class Meta:
        model = User
        fields = ('key', 'email', 'password1', 'password2')

    
    def __init__(self, *args, **kwargs):
        super(MyUserCreationForm, self).__init__(*args, **kwargs)

        self.fields['password1'].widget.attrs['class'] = 'form-control'
        self.fields['password1'].widget.attrs['placeholder'] = 'Password'
        self.fields['password1'].label=''

        self.fields['password2'].widget.attrs['class'] = 'form-control'
        self.fields['password2'].widget.attrs['placeholder'] = 'Confirm Password'
        self.fields['password2'].label=''
        
        for fieldname in ['password1', 'password2']:
            self.fields[fieldname].help_text = None

您最好将获取项目的逻辑移到它所属的表单中。因此:

from django.core.exceptions import ValidationError

class MyUserCreationForm(UserCreationForm):
    # …

    def <strong>clean_key</strong>(self):
        key = self.cleaned_data['key']
        try:
            return RegistrationKey.objects.get(key=key)
        except RegistrationKey.DoesNotExist:
            raise ValidationError('The key is not valid.')

这应该足够了。您不应重写 .form_valid(…) 方法。