我有一个问题,当其中一个字段是我的主键时,如何更新数据库中的现有行。我正在使用ModelForm和Django-Piston - 我的主要目标是将RESTful Post发送到我的webservice。我可以正确发送初始帖子(即主键值尚不存在)。问题是当我想更新主键已存在的值时 - 当我发出f.is_valid()时,它失败,因为“此UniqueIdentifier已经存在”。如何使用ModelForms更新现有行进行表单验证?
我的models.py:
from django.db import models
class DeviceModel(models.Model):
uniqueIdentifier = models.CharField(primary_key=True, max_length=100)
deviceToken = models.CharField(max_length=100)
forms.py
from django import forms
from models import DeviceModel
class DeviceModelForm(forms.ModelForm):
class Meta:
model = DeviceModel
handlers.py
class DeviceHandler(BaseHandler):
allowed_methods = ('POST', 'GET', 'DELETE',)
def create(self, request):
f = DeviceModelForm(request.POST)
if f.is_valid():
new_object = f.save()
return new_object
return rc.BAD_REQUEST
urls.py
from django.conf.urls.defaults import *
from piston.resource import Resource
from api.handlers import DeviceHandler
device_handler = Resource(DeviceHandler)
urlpatterns = patterns('',
(r'^api/$', device_handler, {'emitter_format': 'json'}),
)
答案 0 :(得分:15)
django docs给出了一个如何创建“表单以更改现有[[entity]]”的简单示例:
>>> article = Article.objects.get(pk=1)
>>> form = ArticleForm(instance=article)
如果看起来您想要使用相同的流来插入新对象和更改现有对象,则必须单独实例化该表单,具体取决于查找主键是成功(现有对象)还是失败(new对象) - )
答案 1 :(得分:12)
要更新现有行(或ORM-speak中的对象),您必须告诉ModelForm
实例化时要使用的实例:
f = DeviceModelForm(request.POST, instance=myobject)
我不确定你在哪里使用活塞myobject
,但你的问题似乎暗示你已经解决了这个问题。
答案 2 :(得分:2)
这是一个更完整的解决方案,汇集了此页面上的其他答案和评论。 我把它作为对jquery ajax的回复。
def Save_product(request):
if request.method == "POST":
# first get the model pk we are looking for
postpk = request.POST.get('pk', None)
# get the model from the db
model, created = Product.objects.get_or_create(pk = postpk)
# create the from based on the model, but with the
# request data overriding the model data
form = ProductForm(request.POST, instance = model)
# save if valid
if form.is_valid():
form.save()
return HttpResponse("saved");
else:
# will go to the the ajax error: data.responseText
return HttpResponseNotFound("%s" % (form.errors))
else:
return HttpResponseNotFound('eh? this was not a Post?')
答案 3 :(得分:0)
这是我根据实体是否存在进行更新或创建的工作:
# first see the DeviceModel exists and should simply be updated
try:
instance = DeviceModel.objects.get(mycolumn=data['mycolumn'])
f = DeviceModelForm(data, instance=instance)
except DeviceModel.DoesNotExist:
# DeviceModel doesn't exists, so we create a new one
f = DeviceModelForm(data)
except DeviceModel.MultipleObjectsReturned:
# our query found multiple DeviceModel
# either update them all or throw an error
print("Found multiple DeviceModels")
if f.is_valid():
f.save()