2009-11-23 3 views
10

J'ai une question sur la façon de mettre à jour une ligne existante dans ma base de données lorsque l'un des champs est ma clé primaire. J'utilise ModelForm et Django-Piston - mon objectif principal ici est d'envoyer RESTful Post à mon webservice. Je suis en mesure d'envoyer les messages initiaux correctement (c'est-à-dire que la valeur de clé primaire n'existe pas encore). Le problème est quand je veux mettre à jour une valeur où la clé primaire existe déjà - quand j'émets un f.is_valid() il échoue parce que "cet identifiant unique existe déjà". Comment puis-je effectuer une validation de formulaire à l'aide de ModelForms pour mettre à jour une ligne existante?Comment mettre à jour une ligne déjà existante lors de l'utilisation de ModelForms?

Mon 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

Si une réponse vous a donné les informations dont vous aviez besoin, vous devez l'accepter (cliquez sur la coche). –

Répondre

11

Le django docs donne un exemple simple de la façon de créer « un formulaire pour modifier un existant [[entité]] »:

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

Si comme il vous semble souhaitez utiliser le même flux à la fois pour l'insertion d'une nouvelle objets et en modifiant ceux existants, vous devrez instancier le formulaire séparément selon que la recherche de la clé primaire réussit (objet existant) ou échoue (nouvel objet)! -)

+0

Great - qui a donné moi ce que je voulais! – letsgofast

+1

Lorsque form.save() est appliqué sur le formulaire, l'instance doit être mise à jour avec les données de formulaire? Ma forme l'enregistre dans une nouvelle instance, elle se fait elle-même. – tilaprimera

10

Pour mettre à jour une ligne existante (ou objet ORM-parler), vous devez dire ce ModelForm par exemple à utiliser lors de l'instancier:

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

Je ne sais pas où vous obtenez myobject d'utiliser piston, bien que , mais votre question semble impliquer que vous avez déjà résolu ce problème particulier.

+0

C'était la bonne réponse à mon problème. Il est documenté (mais difficile à trouver) ici https://docs.djangoproject.com/fr/dev/topics/forms/modelforms/#the-save-method (voir le dernier exemple dans la boîte de code) – tutuDajuju

2

Voici une solution plus complète, rassemblant les autres réponses et commentaires sur cette page. Je l'ai comme une réponse à un ajax jquery.

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?') 
Questions connexes