Как обновить уже существующую строку при использовании ModelForms?
у меня есть вопрос о том, как обновить существующую строку в моей базе данных, когда одно из полей-это мой первичный ключ. Я использую ModelForm и Django-Piston - моя главная цель здесь-Отправить сообщение RESTful на мой веб-сервис. Я могу правильно отправлять начальные сообщения (т. е. значение первичного ключа еще не существует). Проблема в том, когда я хочу обновить значение, где первичный ключ уже существует - когда я выпускаю 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'}),
)
4 ответов
на Джанго документы приведите простой пример того, как создать "форму для изменения существующей [[сущности]]":
>>> article = Article.objects.get(pk=1)
>>> form = ArticleForm(instance=article)
если, как кажется, вы хотите использовать один и тот же поток как для вставки новых объектов, так и для изменения существующих, вам придется создавать экземпляр формы отдельно в зависимости от того, успешно ли выполняется поиск первичного ключа (существующий объект) или не удается (новый объект)!-)
чтобы обновить существующую строку (или объект в ORM-speak), вы должны сказать ModelForm
какой экземпляр использовать при его создании:
f = DeviceModelForm(request.POST, instance=myobject)
Я не уверен, где вы получаете myobject
от использования поршня, хотя, но ваш вопрос, похоже, подразумевает, что вы уже решили эту конкретную проблему.
вот более полное решение, объединяющее другие ответы и комментарии на этой странице. У меня он работает как ответ на 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?')
Это то, что я сделал для обновления или создания в зависимости от того, существует ли сущность:
# 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()