Django ModelForm不保存数据到数据库
一个Django初学者在这里遇到很多麻烦的表单工作。 是的,我已经完成了教程并浏览了很多网站 - 我拥有的是我在这里和其他网站找到的内容。 我使用Python 2.7和Django 1.5。 (虽然官方文档非常广泛,但它往往假设你已经知道它的大部分内容 - 不适合作为初学者参考,甚至是高级教程)
我正在尝试为“扩展”用户详细信息创建表单 - 例如。 公司名称,街道地址等,但表单数据并未保存到数据库中。
最初我试图创建一个扩展标准User
模型的模型,但是我放弃了这一点 - 需要修改的太多了,而且在这个阶段它已经超越了我自己。 相反,我创建了一个名为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链接到用户模型。
我正在尝试使用ModelForm(保持简单的形式)。 这是我的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存在不一致 - 这是我所有黑客行为的产物,一旦我得到它就会被修复)
诊断程序显示f.is_valid()
返回True。 同样,诊断程序显示UserProfile.objects.all()
为空。 我在save()和Django控制台之后在上面的视图中试过了。
这是我的模板:
<form method="POST" action="">
<table>{{ form }}</table>
<input type="submit" value="Update" />
{% csrf_token %}
</form>
目前主要的问题是表单数据没有保存到数据库中。 我不知道是否正在读取或不读取(一旦我在数据库中有一些数据...)
一个想法是User
关系可能导致问题?
Addenda,继Daniel Roseman的有用评论/帮助之后:
现在表单正确保存(通过诊断和命令行检查来确认),但是当我回到表单时,它没有显示现有数据,显示了一个空数据字段的表单,据我所知, m正确传递实例数据。
是否有需要更改的ModelForm设置?
这里是修改后的视图:
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源也不显示任何数据值。 作为额外的支票,我还尝试了一些模板诊断:
<table border='1'>
{% for field in form%}
<tr>
<td>{{field.label}}</td>
<td>{{field.value}}</td>
</tr>
{% endfor%}
</table>
这会正确列出字段标签,但这些值都报告为None
。
为了完整user = models.OneToOneField(settings.AUTH_USER_MODEL)
,UserProfile的用户字段现在定义为user = models.OneToOneField(settings.AUTH_USER_MODEL)
,并且User.profile lambda表达式保持不变。
我不确定到底是什么问题,但有一个问题肯定是您在实例化表单时传递instance=request.user
。 这绝对是错的: request.user
是User的一个实例,而表单基于UserProfile
。
相反,你想要做这样的事情:
f = UserDetailsForm(request.POST)
if f.is_valid():
profile = f.save(commit=False)
profile.user = request.user
profile.save()
至于ForeignKey vs OneToOne,你绝对应该使用OneToOne。 关于使用ForeignKeys的建议在Django 1发布之前已经有一段时间了 - 这是大约五年前的事了 - 因为OneToOne的原始实现很差,并且正在改写。 您当然不会在这里找到任何建议使用FK的最新文档。
在注释之后编辑现在的问题是,您正在使用第一个参数data实例化表单,即使请求不是POST,因此request.POST
是空字典。 但是数据参数(即使它是空的)优先于作为初始数据传递的任何数据参数。
您应该回到在if
语句中实例化表单的原始模式 - 但在else
子句中执行时务必不要传递request.POST
。
UserDetailsForm(request.POST, instance = db_obj_form)
db_obj应该是要保存的表UserProfile的一个对象。
链接地址: http://www.djcxy.com/p/77263.html