【问题标题】:How do I update an already existing row when using ModelForms?使用 ModelForms 时如何更新已经存在的行?
【发布时间】:2010-12-19 07:49:13
【问题描述】:

当其中一个字段是我的主键时,我有一个关于如何更新数据库中现有行的问题。我正在使用 ModelForm 和 Django-Piston - 我的主要目标是让 RESTful Post 发送到我的网络服务。我能够正确发送初始帖子(即该主键值尚不存在)。问题是当我想更新主键已经存在的值时 - 当我发出 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'}),
)

【问题讨论】:

  • 如果答案提供了您需要的信息,您应该接受它(点击复选标记)。

标签: python django modelform django-piston


【解决方案1】:

这是一个更完整的解决方案,不使用任何基于类的视图,在此页面上汇集了其他答案和 cmets。

我将它作为对 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?')   

【讨论】:

    【解决方案2】:

    这是我根据实体是否存在来更新或创建的:

    # 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()
    

    【讨论】:

      【解决方案3】:

      django docs 给出了一个简单的例子来说明如何创建“一个表单来改变一个现有的[[entity]]”:

      >>> article = Article.objects.get(pk=1)
      >>> form = ArticleForm(instance=article)
      

      如果您似乎想使用相同的流程来插入新对象和更改现有对象,则必须根据查找主键是成功(现有对象)还是失败(新对象)!-)

      【讨论】:

      • 当 form.save() 应用到表单时,实例应该用表单数据更新吗?我的表单正在将其保存到新实例中,它正在自行生成。
      【解决方案4】:

      要更新现有行(或 ORM 中的对象),您必须告诉 ModelForm 在实例化它时使用什么实例:

      f = DeviceModelForm(request.POST, instance=myobject)
      

      不过,我不确定你从哪里得到 myobject 使用活塞,但你的问题似乎暗示你已经解决了这个特定问题。

      【讨论】:

      猜你喜欢
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多