Django表单数据未保存到数据库

Posted

技术标签:

【中文标题】Django表单数据未保存到数据库【英文标题】:Django form data not saving to database 【发布时间】:2021-10-07 21:49:41 【问题描述】:

我有一个views.py,它将来自不同模型的三个表单组合成模板上的一个表单。该代码似乎是可操作的,views.py 文档中的打印语句表明该表单有效并且所有相关数据都可用。但是,只有来自 form1form2 的数据会保存到数据库中。

我已经阅读了(感觉是)这个网站上的几十个线程,但是打印语句和清除数据库是我最后的生产性调试想法,现在我不知道如何进一步调试.请提出建议!

views.py

def consent(request):
    context = 
        'title': 'Consent',
    
    print(Author)
    try:
        UD = UserDetails.objects.get(user_id=request.user.id)
        consent = UD.participate_consent
        if consent == True:
            username = request.user.username
            messages.warning(request, f'Hej, username, you already did that.')
            return redirect('profile')
    except:
        context['form1'] = None
        context['form2'] = None
        context['form3'] = None
        
        if request.method == 'POST':
            form1 = UserDetailsForm(request.POST)
            form2 = GetUserFirstLast(request.POST, instance=User.objects.get(id=request.user.id))
            form3 = GetAuthorInfo(request.POST, instance=User.objects.get(id=request.user.id))
            context['form1'] = form1
            context['form2'] = form2
            context['form3'] = form3
            if form1.is_valid() and form2.is_valid() and form3.is_valid():
                print(form1.cleaned_data)
                print(form2.cleaned_data)
                print(form3.cleaned_data)
                form1.save()
                form2.save()
                form3.save()
                username = form1.cleaned_data.get('username')
                messages.success(request, f'Thanks for consenting, username! \nNow we can get started.')
                return redirect('profile')
            else:
                print("a form is not valid")
        else:
            form1 = UserDetailsForm()
            form2 = GetUserFirstLast(instance=User.objects.get(id=request.user.id))
            form3 = GetAuthorInfo(instance=User.objects.get(id=request.user.id))
            context['form1'] = form1
            context['form2'] = form2
            context['form3'] = form3

    return render(request, 'users/consent.html', context)

form3相关模型

class Author(models.Model):
    user = models.ForeignKey(User, on_delete=models.PROTECT, primary_key=True)
    username = models.CharField(max_length=100, blank=True)
    slug = slug = models.SlugField(max_length=400, unique=True, blank=True)
    bio = HTMLField()
    points = models.IntegerField(default=0)
    profile_pic = ResizedImageField(size=[50, 80], quality=100, upload_to="static/users/authors/", default='static/users/authors/default.png')

    def __str__(self):
        return self.username

    @property
    def num_posts(self):
        return Post.objects.filter(user=self).count()
    

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.username)
        super(Author, self).save(*args, **kwargs)

form3相关的forms.py

class  GetAuthorInfo(forms.ModelForm):
    user = forms.CharField(widget=forms.HiddenInput(), required=True)
    profile_pic = forms.ImageField(label = profile_pic_label, required=False, initial='static/users/authors/default.png') 
    bio = forms.CharField(label = bio_label, widget=forms.Textarea())
    username = forms.CharField(widget=forms.HiddenInput(), required=True)

    class Meta:
        model = Author
        fields = ['user', 'profile_pic', 'bio', 'username']

编辑开始 遵循(或尝试)遵循答案中的建议,表单现在看起来像

class  GetAuthorInfo(forms.ModelForm):

    class Meta:
        model = Author
        fields = '__all__'
        exclude = ['points']

        labels = 
            'profile_pic': profile_pic_label,
            'bio': bio_label
        

        widgets = 
            'bio': forms.Textarea(),
            'username': forms.HiddenInput()
        

但还是不行。 编辑结束

模板的相关部分

            <form method="POST">
                % csrf_token %
                <fieldset class="form-group">
                    <legend class="border-bottom mb-4">% translate 'Informed Consent' %</legend>
                     form2|crispy 
                     form1|crispy 
                    <h4>For the forum</h4><hr>
                    <img src="% static 'users/authors/default.png' %" style="height:150px;width:200px;">
                     form3|crispy 
                    <input type="hidden" name="user" value=" user.id ">
                    <input type="hidden" name="username" value=" user.username ">
                </fieldset>
                <div class="form-group">
                    <button class="btn btn-outline-info" type="submit">% translate 'Submit' %</button>
                </div>
                <div> form.errors </div>
            </form>

Django 版本 3.2.5

Python 版本 3.8.10

操作系统 Linux Mint 20.1

请!

【问题讨论】:

【参考方案1】:

表单具有文件字段,因此您可以在视图中请求文件 像这样

form3 = GetAuthorInfo(request.POST,request.FILES, instance=User.objects.get(id=request.user.id))

在你的 html 代码中

<form method="POST" enctype="multipart/form-data"> 

请稍微改变一下你的表格

class  GetAuthorInfo(forms.ModelForm):
    class Meta:
        model = Author
        fields = '__all__'
        exclude = ['slug']
        # if you want to add widgets & labels to fields like
        labels = 
        'dob':'Date Of Birth',
        
        widgets = 
        'dob': forms.DateInput(attrs='type': 'date')
        

【讨论】:

我将 request.FILES 和 profile_pic 字段从模型中取出(并重新迁移等),看看这是否是问题所在,但忘记将其放回原处。然后没有任何变化——没有 profile_pic 字段仍然没有保存到模式中。尽管如此,按照您的建议,仍然没有数据保存到数据库中。 因为我就是这样学到的——可能是错误的——你应该指明“所有”字段或只指明你想要的字段。在这种特殊情况下,我不想用这个表单填充points(这是问题,因为我没有从调试中恢复),所以目的是除了点之外的所有字段。 当用户已经连接外键时,您不必添加额外的字段用户名 @Bob 试试这个告诉我你是否还有错误【参考方案2】:

fields = ['user', 'bio', 'username', 'profile_pic']

【讨论】:

感谢您的建议,但没有任何改变。

以上是关于Django表单数据未保存到数据库的主要内容,如果未能解决你的问题,请参考以下文章

页面未在 django 中保存表单数据

HTML表单数据未保存在数据库中 - django

Django,模型表格未在数据库中保存数据

Django绑定表单无效,但未引发ValidationError

Django With MSSQL using Pyodbc:未保存模型表单

Django 表单视图:M 到 M 值未保存