Django - forms.Form 无法保存当前用户并且表单有效但未保存
Posted
技术标签:
【中文标题】Django - forms.Form 无法保存当前用户并且表单有效但未保存【英文标题】:Django - forms.Form can't save current user and form is valid but not saved 【发布时间】:2015-12-04 02:20:03 【问题描述】:我修改了我的代码以使用forms.ModelForm
,以便我可以修改网页表单的宽度。我现在遇到的问题是ForeignKeys
不适用于forms.Form,我需要在form中保存活动用户,以及提交请求的当前时间。
以下是我使用当前解决方法的文件(我排除了所有必要的导入),它给了我以下错误:table chemrun_chemrun has no column named owner_id
。我很高兴有任何帮助来解决这个问题:)
来自models.py
class ChemRun(models.Model):
owner = models.ForeignKey('auth.User')
来自forms.py
class ChemRunForm(forms.ModelForm):
title = forms.CharField(max_length=50)
status = forms.CharField(max_length=20, initial="In queue")
created_date = forms.DateTimeField(initial=timezone.now, required=False)
def __unicode__(self):
return self.title
class Meta:
model = ChemRun
exclude = 'created_date', 'status', 'owner'
来自views.py
@verified_email_required
def create(request):
if request.POST:
form = ChemRunForm(request.POST)
if form.is_valid():
m = form.save(commit=False)
m.created_date = timezone.now
m.owner = request.user
m.save()
return HttpResponseRedirect('/accounts/profile')
else:
form = ChemRunForm()
args =
args.update(csrf(request))
args['form'] = form
return render_to_response('interface/newrun.html', args, context_instance=RequestContext(request))
来自 urls.py
urlpatterns = [
url(r'^create/$', 'chemrun.views.create', name='create'),
]
【问题讨论】:
“我修改了我的代码以使用 forms.Form 以便我可以修改表单的宽度” - 根本没有遵循。您可以以完全相同的方式修改 ModelForm 的字段宽度。 我的错,我的意思是写我修改为使用forms.ModelForm
这似乎与表单无关。错误消息说缺少列;这意味着您尚未创建和运行迁移。
好的,我尝试了 makemigrations 调用,并收到以下消息 You are trying to add a non-nullable field 'owner' to chemrun without a default; we can't do that (the database needs something to populate existing rows).
在进行这些更改之前,使用与现在相同的命令将当前用户添加到我的表单中没有问题:owner = models.ForeignKey('auth.User')
。特别是,我不需要添加默认值来分配所有者值,但现在出于某种原因我需要。
不,这是不可能的。在运行迁移之前,您将无法将用户添加到对象中,因为您没有外键。该错误消息告诉您需要为 现有 对象提供一次性默认值,而不是任何新对象。
【参考方案1】:
我看到了两个实用的解决方案:
-
由于字段“所有者”是模型中的新字段,因此您必须在迁移中添加一个默认 id,以将其放入已存在数据的列中。
您可以在 'owner' 字段中设置 'blank=null',这样 django 就不会强制该列中的数据。
您在 cmets 中说过,在命令 'makemigrations' 之前没有要求您提供任何东西,而现在它确实要求您提供任何东西,这是因为现在您在该表中有记录,如果您添加新列,django 或 postgres 都不知道在旧记录的那一列中放什么,也许你可以“刷新”你的数据库?当然,前提是它是一个开发数据库。
【讨论】:
谢谢,我刚刚对此进行了测试,在删除数据库和所有以前的迁移后,页面运行。现在唯一剩下的问题是表单收集的数据没有保存到数据库中,否则无法访问数据库。 您删除数据库中的数据后是否再次运行makemigrations? 是的,我创建了一个超级用户来访问管理页面,并创建了一个普通用户来运行脚本来创建表单。manage.py makemigrations
给我No changes detected
你是否在 makemigrations 之后运行了 migrate?
是的,我还运行了 collectstatic 以防万一。什么都没有【参考方案2】:
经过更多的阅读和实验,我发现了一些额外的要点,可以为该问题的未来读者添加。
错误的第一部分是由于无法成功运行命令makemigrations
和随后的migrate
而导致的。由于错误,我从迁移目录中删除了__init__.py
。恢复文件并重新运行命令后,该部分已得到纠正。对于未来,我可以推荐以下脚本来清理/重置迁移(取自this question 的答案之一)。
#!/bin/sh
echo "Starting ..."
echo ">> Deleting old migrations"
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
# Optional
echo ">> Deleting database"
find . -name "db.sqlite3" -delete
echo ">> Running manage.py makemigrations"
python manage.py makemigrations
echo ">> Running manage.py migrate"
python manage.py migrate
echo ">> Done"
第二部分是能够调整字段的宽度。我在 models.py 中定义了我的字段,但是通过在 forms.py 中添加对等价表单类的 Meta 类的小部件调用,我可以调整它等等。这是我的forms.py:
class ChemRunForm(forms.ModelForm):
class Meta:
model = ChemRun
widgets = 'title': forms.TextInput(attrs='style':'width: 500px;')
exclude = ('owner')
注意:ChemRun
是模型类,ChemRunForm
是表单类。 title
和 owner
是我模型的两个字段。
希望这对未来的人们有所帮助
【讨论】:
以上是关于Django - forms.Form 无法保存当前用户并且表单有效但未保存的主要内容,如果未能解决你的问题,请参考以下文章