Django ModelForm没有将数据保存到数据库 [英] Django ModelForm not saving data to database

查看:141
本文介绍了Django ModelForm没有将数据保存到数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里的Django初学者在使表格正常工作时遇到很多麻烦.是的,我已经完成了本教程并浏览了很多网络-我所得到的是我在这里和其他站点上所发现的内容的混合体.我正在使用Python 2.7和Django 1.5. (尽管官方文档内容广泛,但它往往会假设您已经了解了其中的大部分内容-不适合作为初学者参考书,甚至不适合作为高级教程使用)

A Django beginner here having a lot of trouble getting forms working. Yes I've worked through the tutorial and browsed the web a lot - what I have is mix of what I'm finding here and at other sites. I'm using Python 2.7 and Django 1.5. (although the official documentation is extensive it tends to assume you know most of it already - not good as a beginners reference or even an advanced tutorial)

我正在尝试为扩展的"用户详细信息创建表单-例如公司名称,街道地址等,但表格数据未保存到数据库中.

I am trying to create a form for "extended" user details - eg. company name, street address, etc but the form data is not being saved to the database.

最初,我试图创建一个扩展标准User模型的模型,但是我放弃了–太多的修改需要修改,在这个阶段它已经超出了我的理解范围. 因此,我创建了一个名为UserProfile的新模型:

Initially I tried to create a model extending the standard User model, but I gave up on that - too much needed modifying and it was getting into nitty gritty that was way beyond me at this stage. So instead I have created a new model called UserProfile:

class UserProfile(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, unique=True) 
    company = models.CharField(max_length=50, blank=True)
    address1 = models.CharField(max_length=50, blank=True)
    address2 = models.CharField(max_length=50, blank=True)
    city = models.CharField(max_length=20, blank=True)
    region = models.CharField(max_length=20, blank=True)
    postcode = models.CharField(max_length=10, blank=True)
    country = models.CharField(max_length=20, blank=True)
    phone = models.CharField(max_length=30, blank = True)

关于我应该使用ForeignKey(如上所述)还是使用OneToOne链接到User模型,我在网上看到了不同的参考文献.

I have seen different references online as to whether I should link to the User model with a ForeignKey (as above) or with a OneToOne.

我正在尝试使用ModelForm(对于应该是简单形式的形式,请使其保持简单).这是我的forms.py

I am trying to use a ModelForm (keep it simple for what should be a simple form). Here is my forms.py

from django.forms import ModelForm
from .models import UserProfile   

class UserDetailsForm(ModelForm):
    class Meta:
        model = UserProfile
        fields = ['company','address1','address2','city','region', 'postcode','country','phone']

这是我的观点:

def UserDetailsView(request):
    #f = 0
    if request.method == 'POST':
        f = UserDetailsForm(request.POST, instance = request.user)
        if f.is_valid():
            f.save()
    else:
        f = UserDetailsForm(request.POST , instance = request.user)

    print "UserDetails objects: ", (UserProfile.objects.all()) 

    return render_to_response('plagweb/console/profile.html', 
                              { 'form': f}, 
                              context_instance=RequestContext(request))     

(是的,UserProfile与UserDetail之间存在不一致-这是我所有黑客攻击的产物,一旦我可以正常使用,将予以修复)

(yes there is an inconsistency in UserProfile vs UserDetail - this is a product of all my hacking and will be fixed once I get it working)

诊断显示f.is_valid()返回True. 同样,诊断显示UserProfile.objects.all()为空.我在save()之后的上述视图中以及在Django控制台中尝试了此操作.

Diagnostics show f.is_valid() returning True. Similarly, diagnostics show UserProfile.objects.all() as being empty. I tried this in the above view after the save(), and also at the Django console.

这是我的模板:

 <form method="POST" action="">
 <table>{{ form }}</table>
 <input type="submit" value="Update" />
 {% csrf_token %}
 </form>

当前的主要问题是表单数据没有保存到数据库中.我不知道是否正在读取(一旦数据库中有一些数据...)

At the moment the main problem is that form data is not being saved to the database. I do not know if is being read yet or not (once I have some data in the database...)

一个想法是User关系可能会引起问题吗?

One thought is that the User relationship might be causing a problem?

附录,紧接着Daniel Roseman的有用评论/帮助:

Addenda, following on from Daniel Roseman's useful comment/help:

现在该表单可以正确保存(已通过诊断和命令行检查确认.但是,当我返回该表单时,它不显示现有数据.将显示一个带有空数据字段的表单.据我所知,我正确传递了实例数据.

Now the form is saving correctly (confirmed with diagnostics and command line checks. However when I go back to the form, it is not displaying the existing data. A form with empty data fields is displayed. As far as I can tell, I'm passing the instance data correctly.

是否有需要更改的ModelForm设置?

Is there a ModelForm setting that needs to change?

这是修改后的视图:

def UserDetailsView(request):
    #print "request co:", request.user.profile.company
    f = UserDetailsForm(request.POST, instance = request.user.profile )

    if request.method == 'POST':
        if f.is_valid():
            profile = f.save(commit=False)
            profile.user = request.user
            profile.save()

    return render_to_response('plagweb/console/profile.html', 
                              { 'form': f}, 
                              context_instance=RequestContext(request))     

诊断表明request.user.profile设置正确(特别是公司字段).但是,窗体显示为空字段. HTML源也不显示任何数据值. 作为一项额外的检查,我还尝试了一些模板诊断程序:

The diagnostics show that request.user.profile is set correctly (specifically the company field). However the form is displayed with empty fields. The HTML source doesn't show any data values, either. As an extra check, I also tried some template diagnostics:

<table border='1'>
    {% for field in form%}
        <tr>
            <td>{{field.label}}</td>
            <td>{{field.value}}</td>
        </tr>
    {% endfor%}
</table>

这将正确列出字段标签,但所有值均报告为None.

This lists the field labels correctly, but the values are all reported as None.

为完整起见,现在将UserProfile的用户字段定义为user = models.OneToOneField(settings.AUTH_USER_MODEL),而User.profile lambda表达式未更改.

For completeness, the UserProfile's user field is now defined as user = models.OneToOneField(settings.AUTH_USER_MODEL) and the User.profile lambda expression is unchanged.

推荐答案

我不确定这里到底是什么问题,但是肯定有一个问题是您在实例化表单时传递了instance=request.user.绝对是错误的:request.user是User的实例,而表单基于UserProfile.

I'm not sure exactly what the problem is here, but one issue certainly is that you are passing instance=request.user when instantiating the form. That's definitely wrong: request.user is an instance of User, whereas the form is based on UserProfile.

相反,您想要执行以下操作:

Instead, you want to do something like this:

f = UserDetailsForm(request.POST)
if f.is_valid():
    profile = f.save(commit=False)
    profile.user = request.user
    profile.save()

关于ForeignKey与OneToOne,您绝对应该使用OneToOne.在将近五年前的Django 1发行前的一段时间里,就给出了使用ForeignKeys的建议,这是因为OneToOne的原始实现很差,并且将被重写.您当然不会在这里找到任何建议使用FK的最新文档.

As regards ForeignKey vs OneToOne, you should absolutely be using OneToOne. The advice on using ForeignKeys was given for a while in the run-up to the release of Django 1 - almost five years ago now - because the original implementation of OneToOne was poor and it was due to be rewritten. You certainly won't find any up-to-date documentation advising the use of FK here.

在注释后编辑现在的问题是,即使请求不是POST,因此request.POST是空字典,您也要使用第一个参数data实例化表单.但是data参数(即使为空)也优先于作为初始数据传递的内容.

Edit after comments The problem now is that you're instantiating the form with the first parameter, data, even when the request is not a POST and therefore request.POST is an empty dictionary. But the data parameter, even if it's empty, takes precedence over whatever is passed as initial data.

您应该回到在if语句中实例化表单的原始模式-但是请确保在else子句中进行操作时不要传递request.POST.

You should go back to the original pattern of instantiating the form within the if statement - but be sure not to pass request.POST when doing it in the else clause.

这篇关于Django ModelForm没有将数据保存到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆