Django没有将表单提交到数据库

Posted

技术标签:

【中文标题】Django没有将表单提交到数据库【英文标题】:Django not committing form to database 【发布时间】:2017-06-12 12:49:17 【问题描述】:

用例是登录用户,可以将他们的个人资料调用到一个表格中,对其进行编辑并在数据库中更新。

使用下面的代码可以查看正确的个人资料数据。它也可以调用为可编辑的形式。表单允许编辑数据,但提交时,数据库不更新,显示原始配置文件。

我已经尝试了一切,包括控制台打印语句,所以我知道它正在进入代码的 POST 部分,是一个有效的表单并执行初始 save()。

任何见解都将不胜感激(我使用的是 Django 1.11)。我不想让兔子开始跑步,但我唯一没有尝试过的是打破与用户的 OneToOne 关系并使用外键,因为我希望在用户注册时创建个人资料条目。

注意事项: 当我出于测试目的将其弹出时: save_data.user = request.user 我收到错误:异常值:'用户'对象没有属性'cleaned_data'`来自 django.db 导入模型 从 django.contrib.auth.models 导入用户 从 django.db.models.signals 导入 post_save

Models.py

    from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    description = models.CharField(max_length=100, default='')
    city = models.CharField(max_length=100, default='')
    website = models.URLField(default='')
    phone = models.IntegerField(default=0)
    balance = models.FloatField(default=0)
    bank  = models.FloatField(default=0)
    image = models.ImageField(upload_to='profile_image', blank=True)

    def __str__(self):
        return self.user.username

def create_profile(sender, **kwargs):
    if kwargs['created']:
        user_profile = UserProfile.objects.create(user=kwargs['instance'])

post_save.connect(create_profile, sender=User)

Forms.py

from django import forms
from django.contrib.auth.models import User
from .models import UserProfile

class ProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('description', 'city', 'phone', 'balance', 'bank', 'website', 'image')

Views.py

from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.contrib.auth import login, authenticate, update_session_auth_hash
from django.contrib.auth.forms import (
        UserCreationForm,
        UserChangeForm,
        PasswordChangeForm
        )
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from core.forms import ( EditAccountForm, SignUpForm,
                        ProfileForm
                        )
from core.models import UserProfile
from django.views.generic import (TemplateView,ListView,
                                  DetailView,CreateView,
                                  UpdateView,DeleteView)

# Create your views here.
def edit_profile(request):
    if request.method == 'POST':
        form = ProfileForm(request.POST, instance=request.user)
        if form.is_valid():
            save_data = form.save()
            save_data.user = request.user
            print(save_data)
            save_data.save()
            return redirect(reverse('core:profile'))
    else:
        udata = UserProfile.objects.get(user=request.user)
        form = ProfileForm(instance=udata)
        args = 'form': form
        return render(request, 'core/test.html', args)

urls.py

from django.conf.urls import url
from django.contrib import admin
#from playme.core import views as core_views
from core import views as core_views
from django.contrib.auth import views as auth_views

# SET THE NAMESPACE!
app_name = 'core'


urlpatterns = [
    url(r'^$', core_views.index, name='index'),
    url(r'signup/$', core_views.signup, name='signup'),
    url(r'^account/$', core_views.account, name='account'),
    url(r'^profile/$', core_views.view_profile, name='profile'),
    url(r'^login/$', auth_views.login, 'template_name': 'core/login.html', name='user_login'),
    url(r'^logout/$', auth_views.logout, 'next_page': '/play/', name='logout'),
    url(r'^edit_account/$', core_views.edit_account, name='edit_account'),
    url(r'^edit_profile/$', core_views.edit_profile, name='edit_profile'),
    url(r'^change_password/$', core_views.change_password, name='change_password'),
]

我点击的网址是: http://127.0.0.1:8000/play/profile/ 然后转到: http://127.0.0.1:8000/play/edit_profile/

表单会加载,但提交后会返回: http://127.0.0.1:8000/play/profile/

没有数据库更新。

【问题讨论】:

【参考方案1】:

我很惊讶这没有给出错误。

当您在 GET 上实例化表单时,您正确地将 UserProfile 对象作为 instance 参数传递 - 这是正确的,因为表单将其作为模型。但是当您在 POST 上实例化时,您错误地传递了用户对象 - request.user。您应该像在另一个分支中一样传递配置文件。

注意,在这两种情况下,您都可以通过 request.user.userprofile 更简单地获取配置文件。

【讨论】:

所以你在 POST 区域中说的是:form = ProfileForm(request.POST, instance=request.user) 应该是 form = ProfileForm(request.POST , instance=request.user.userprofile) ?因为在 if form.is_valid(): 之后进行调试时,我从 form 打印了清理后的数据,并且它具有正确的表单数据。 是的,这正是我要说的。您的调试显示表单数据是正确的,但这不是您的问题;如果您不提供数据,它将无法将数据保存到 UserProfile。 辛苦了。谢谢你。我仍然不完全理解你在那里做了什么,所以如果你有时间解释一下,我将不胜感激。但永远不会少,非常感谢。 3 天后,这太棒了。【参考方案2】:

好吧,这里根本没有处理表单无效的情况。你的代码应该是这样的

def edit_profile(request):
    if request.method == 'POST':
        form = ProfileForm(request.POST, instance=request.user)
        if form.is_valid():
            save_data = form.save(commit=False)
            save_data.user = request.user
            save_data.save()
            return redirect(reverse('core:profile'))
    else:
        udata = UserProfile.objects.get(user=request.user)
        form = ProfileForm(instance=udata)
        args = 'form': form
    return render(request, 'core/test.html', args)

注意缩进的变化。

【讨论】:

好的,我复制了你的代码,它运行没有错误。 (谢谢)。但是没有任何变化,我提交表单后,数据并没有保存到数据库中。

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

python Django 如何在表单提交之后页面上仍存在用户填好的数据?

提交表单后,Django 没有更新我的数据库

django 编辑表单,数据怎么回显呀

HTML表单提交到.HTML实例

如何将从表单提交中检索到的参数作为参数传递给 django 中的函数

提交表单html django