Skip to main content
 首页 » 编程设计

python之Django CBV UpdateView 未将表单保存到数据库。 ( Django 2.0)

2024年12月31日24小虾米

我是 Django 的新手,目前正在做一个副项目。 我有两个模型 User 和 Profile,它们具有一对一的关系。

我已经创建了 post_save 信号,所以当新用户注册时,他的空配置文件实例已经在数据库中创建。

def create_profile(sender, instance, created, **kwargs): 
    if created: 
        Profile.objects.create(user=instance) 
 
post_save.connect(create_profile, sender=CustomUser) 

既然已经创建了配置文件,我想为什么不跳过 CreateView 并使用 UpdateView 来保存配置文件表单。

通过这样做,我只需要为配置文件创建一个表单。所以我只有一个 View ,即 UpdateView。

当用户创建他的帐户时,他被引导到个人资料(自动创建)表单,他在其中保存(更新)他的信息。

现在,当我在 updateView 模板中提交表单时,没有任何内容保存在数据库中,但是,表单通过管理面板成功保存,并且由于它是更新表单,因此从数据库中正确填充了字段。 我认为问题在于发布数据,因为从管理员保存时字段显示正确的数据。

可能是什么问题?

查看

class ProfileSettingsView(UpdateView): 
    model = Profile 
    form_class = ProfileSettingsForm 
    pk_url_kwarg = 'pk' 
    context_object_name = 'object' 
    template_name = 'profile_settings.html' 
 
    def get_object(self): 
        pk = self.kwargs.get('pk') 
        return get_object_or_404(Profile, id=pk) 
 
    def get_context_data(self, **kwargs): 
        c_object = self.get_object() 
        context = super(ProfileSettingsView,  
        self).get_context_data(**kwargs) 
 
        context['linked_in'] = c_object.linked_in 
        context['facebook'] = c_object.facebook 
        print('context: ', context) 
        return context 

模板

<form style="padding-left: 15px; padding-right:15px;" method="POST"> 
    {% csrf_token %} 
 
    <h3>Basic Information</h3> 
 
    <div class="col-lg-6"> 
        <div class="form-group"> 
            <div class="field"> 
                <label>Facebook<span class="red-txt">*</span></label> 
                <input class="form-control" type="text" name="facebook" value="{{ facebook }}" maxlength="60" size="50"> 
            </div> 
        </div> 
    </div> 
 
    <div class="col-lg-6"> 
        <div class="form-group"> 
            <div class="field"> 
                <label>Linked In<span class="red-txt">*</span></label> 
                <input class="form-control" type="text" name="linked_in" value="{{ linked_in }}" maxlength="60" size="50"> 
            </div> 
        </div> 
    </div> 
 
    <div style="padding-bottom:30px; text-align:center;" class="login login-button"> 
        {# <a href="" class="btn btn-outline-primary btn-lg"></a> #} 
        <input type="submit" class="btn btn-outline-primary btn-lg" value="Save Profile"> 
    </div> 
</form> 

型号

class Profile(models.Model): 
    user          = models.OneToOneField(User, on_delete=models.CASCADE) 
    linked_in     = models.CharField(max_length=30, null=True, blank=True) 
    facebook      = models.CharField(max_length=30, null=True, blank=True) 

表格

class ProfileSettingsForm(forms.ModelForm): 
 
    class Meta: 
        model = Profile 
        fields = '__all__' 

请您参考如下方法:

您已经复制了表单、 View 和模板的许多功能,并且在这样做的过程中您绕过了会告诉您哪里出了问题的东西。

您遇到的具体问题是您的表单无效。这是因为您已将其定义为期望 Profile 模型中的所有三个字段,但您没有在提交的数据中提供用户。您没有在页面上看到它,因为您没有显示表单给您的错误,也没有重新显示输入的数据。这些事情都由 Django 为您完成,但您可以通过在 HTML 中对字段进行硬编码来避免它们。

此外,您的大部分 View 代码都是无关紧要的。您的 View 应该仅如下所示:

class ProfileSettingsView(UpdateView): 
    model = Profile 
    form_class = ProfileSettingsForm 
    template_name = 'profile_settings.html' 

因为所有方法和其他属性都是不必要的。您的表格应该是:

class ProfileSettingsForm(forms.ModelForm): 
 
    class Meta: 
        model = Profile 
        fields = ['linked_in', 'facebook'] 
        widgets = { 
            'linked_in': forms.TextInput({'class': 'form-control'}), 
            'facebook': forms.TextInput({'class': 'form-control'}), 
        } 

现在您的模板可以是:

<form style="padding-left: 15px; padding-right:15px;" method="POST"> 
 
    {{ form.errors }} 
 
    {% csrf_token %} 
 
    <h3>Basic Information</h3> 
 
    <div class="col-lg-6"> 
        <div class="form-group"> 
            <div class="field"> 
                <label>Facebook<span class="red-txt">*</span></label> 
                {{ form.facebook }} 
            </div> 
        </div> 
    </div> 
 
    <div class="col-lg-6"> 
        <div class="form-group"> 
            <div class="field"> 
                <label>Linked In<span class="red-txt">*</span></label> 
                {{ form.linked_in }} 
            </div> 
        </div> 
    </div> 
 
    <div style="padding-bottom:30px; text-align:center;" class="login login-button"> 
        {# <a href="" class="btn btn-outline-primary btn-lg"></a> #} 
        <input type="submit" class="btn btn-outline-primary btn-lg" value="Save Profile"> 
    </div> 
</form>