ModelForm 编辑数据库记录的正确方法?
ModelForm right approach for editing database record?
有人可以帮我修复 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>
尝试基于 Class 的视图,最简单的视图如下所示:
from django.views import generic
class HardwareEditView(generic.UpdateView):
template_name = "hardware.html"
form_class = Manage
您必须将 get_absolute_url 添加到模型中。
基于 class 的通用视图完全适用于此标准 create/update/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
:
fields = ['hostname', 'os', 'cpu', 'ram_total', 'storage']
这些字段将在您调用 form.save()
时设置或更新。
我认为这样的事情 - 使用 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'))
........
有人可以帮我修复 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>
尝试基于 Class 的视图,最简单的视图如下所示:
from django.views import generic
class HardwareEditView(generic.UpdateView):
template_name = "hardware.html"
form_class = Manage
您必须将 get_absolute_url 添加到模型中。 基于 class 的通用视图完全适用于此标准 create/update/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
:
fields = ['hostname', 'os', 'cpu', 'ram_total', 'storage']
这些字段将在您调用 form.save()
时设置或更新。
我认为这样的事情 - 使用 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'))
........