【问题标题】:Django form data not saving to databaseDjango表单数据未保存到数据库
【发布时间】: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

请!

【问题讨论】:

    标签: django django-database


    【解决方案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']

    【讨论】:

    • 感谢您的建议,但没有任何改变。
    猜你喜欢
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 2018-05-16
    • 2021-06-28
    • 2017-03-06
    • 1970-01-01
    相关资源
    最近更新 更多