python - ModelForm 编辑数据库记录的正确方法?

标签 python django web django-forms modelform

有人可以帮我修复 Django ModelForm 吗?

此特定代码可以按预期向数据库添加新项目,但当我尝试编辑数据库记录时 - 它只是添加新记录,而不是更新旧记录。我是 Django 框架的新手。

views.py:

def manage(request, item_id = None):
    t = get_object_or_404(Hardware, id=item_id) if item_id else None
    form = Manage(request.POST or None, instance=t)

if t:
    if form.is_valid():
        #form.save()
        hostname = form.cleaned_data['hostname']
        cpu = form.cleaned_data['cpu']
        os = form.cleaned_data['os']
        ram = form.cleaned_data['ram_total']
        storage = form.cleaned_data['storage']
        hostdata = Hardware(
        hostname=hostname,
        cpu=cpu,
        ram_total=ram,
        os=os,
        storage=storage,
        lock_state=t.lock_state, # because in edit operation we shouldn't change it.
        lock_date=t.lock_date, # because in edit operation we shouldn't change it.
        locked_by=t.locked_by) # because in edit operation we shouldn't change it.
        hostdata.save()
        return HttpResponseRedirect(reverse('main:index'))
elif not t:
    if form.is_valid():
        hostname = form.cleaned_data['hostname']
        cpu = form.cleaned_data['cpu']
        os = form.cleaned_data['os']
        ram = form.cleaned_data['ram_total']
        storage = form.cleaned_data['storage']
        current_user = request.user
        user = User.objects.get(id=current_user.id)
        hostdata = Hardware(
        hostname=hostname,
        cpu=cpu,
        ram_total=ram,
        os=os,
        storage=storage,
        lock_state=0,
        lock_date=datetime.datetime.now(),
        locked_by=user)
        hostdata.save()
        return HttpResponseRedirect(reverse('main:index'))

return render(request, 'hardware/edit.html', {'form': form})

模型.py:

class Hardware(models.Model):
    hostname = models.CharField(max_length=255, default=None)
    os = models.CharField(max_length=255, default=None)
    cpu = models.CharField(max_length=255, default=None)
    ram_total = models.CharField(max_length=255, default=None)
    storage = models.CharField(max_length=255, default=None)
    lock_state = models.BooleanField(default=0)
    locked_by = models.ForeignKey(User)
    lock_date = models.DateTimeField(default=None)
    alive = models.BooleanField(default=0)

class Meta:
    db_table = "hardware"

def __str__(self):
    return self.hostname

表单.py:

class Manage(forms.ModelForm):
    class Meta:
        model = Hardware
        fields = ['hostname', 'os', 'cpu', 'ram_total', 'storage']

urls.py:

url(r'^manage/new/$', views.manage, name='add'),
url(r'^manage/edit/(?P<item_id>[0-9]+)/$', views.manage, name='edit')

模板:

<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save!" />
</form>

最佳答案

您已经在 View 的第一行检索了实例 t。下面的代码将始终创建一个新实例(除非您指定 pk 参数):

 hostdata = Hardware(...)
 hostdata.save()

只需这样做:

 if t:
     if form.is_valid():
         t.hostname = form.cleaned_data['hostname']
         t.cpu = form.cleaned_data['cpu']
         ....
         t.save()

但是,您确实应该像其他答案所建议的那样依赖 ModelForm 提供的 save 方法。这是一个例子:

 def manage(request, item_id=None):
     t = get_object_or_404(Hardware, id=item_id) if item_id else None

     # if t is None, a new object will be created in form.save()
     # if t is an instance of Hardware, t will be updated in form.save()
     form = Manage(request.POST, instance=t)

     if form.is_valid():
         form.save()
         return HttpResponseRedirect(reverse('main:index')

     return render(request, 'hardware/edit.html', {'form': form})

您还在表单中指定了字段:

fields = ['hostname', 'os', 'cpu', 'ram_total', 'storage']

这些字段将在您调用 form.save() 时设置或更新。

关于python - ModelForm 编辑数据库记录的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35278353/

相关文章:

python - 用于将 Python 多行字符串与转义字符匹配的正则表达式

django - Puput(基于 Wagtail 的博客)- 文件在哪里?

javascript - 如何断开opentok中的 session ?

google-chrome - Flutter 文本没有完全显示

javascript - 检测页面是否在Grails中成功呈现

python - 如何在 Python 中(自动)测量函数的执行时间

python - 在找到 GPU 后,如何强制 tensorflow 忘记它?

python - 绘制直方图箱的箱线图以进行直方图比较

python - @login_required 之后的 Django 重定向到下一个

Django EmailField 和带有名字和姓氏的完整电子邮件地址