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

时间:2016-02-08 20:07:34

标签: 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})

models.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

forms.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>

3 个答案:

答案 0 :(得分:1)

您已在视图的第一行检索了实例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()

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

 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

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

这些是您致电form.save()时将设置或更新的字段。

答案 1 :(得分:1)

我认为这样的事情 - 使用update_fields - 应该有效:

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

if t:
    if form.is_valid():
        #form.save()
        t.hostname = form.cleaned_data['hostname']
        t.cpu = form.cleaned_data['cpu']
        t.os = form.cleaned_data['os']
        t.ram = form.cleaned_data['ram_total']
        t.storage = form.cleaned_data['storage']   
        t.save(update_fields=['hostname', 'cpu', 'os','ram','storage'])
        return HttpResponseRedirect(reverse('main:index')) 
........

答案 2 :(得分:-1)

尝试基于类的视图,它最简单的看起来像:

:optin

您必须将get_absolute_url添加到模型中。 基于通用类的视图完全适用于此标准创建/更新/视图常见任务。