2010-09-06 3 views
3

J'ai un objet django complexe, qui a des propriétés d'autres types de classe. Cela se présente comme suit:ID de base de données de formulaire et d'objets Django

class Order: 
    contractor - type Person 
    some other fields.... 

Dans ma forme, je voudrais être en mesure de choisir soit l'objet Personne existante dans la liste déroulante ou ajouter une nouvelle avec un formulaire. J'ai réussi à créer des formulaires et un flux de travail approprié, mais le problème consiste à enregistrer l'ordre lui-même, je ne peux tout simplement pas obtenir l'identifiant d'une instance Person enregistrée. Je fais qqch comme ceci:

def make_order(request): 
    if request.method == 'POST': 
    parameters = copy.copy(request.POST) 
    contractor_form = ContractorForm(parameters) 
    if contractor_form.is_valid(): 
     contractor_form.save() 
     parameters['contractor'] = ??? 
    form = OrderForm(parameters) 
    if form.is_valid(): 
     form.save() 
     return HttpResponseRedirect('/orders/') 
    else: 
    form = OrderForm() 
    contractor_form = ContractorForm() 

    return render_to_response('orders/make_order.html', {'order_form' : form, 'contractor_form' : contractor_form}) 

Ainsi, si la demande POST atteint cette méthode j'ai vérifier si ContractorForm ont été remplies - Je suppose que si la forme est valide, il est destiné à être utilisé. Si oui, que je l'enregistre et que je souhaite assigner l'identifiant de la base de données de l'objet sauvegardé au champ approprié pour que OrderForm le trouve.

Tous mes formulaires sont ModelForms.

Les questions sont les suivantes:

  1. Y at-il de meilleures façons de le faire? (choisir parmi une liste déroulante ou ajouter en place) - mieux ou plus pythonique ;-)
  2. Comment puis-je obtenir des ID d'objets enregistrés lors de l'utilisation ModelForms?

Edité

Mon ContractorForm est:

class ContractorForm(ModelForm): 
    class Meta: 
    model = Contractor 

Rien de fantaisie.

+2

Sur une note de côté, inverse l'utilisation (http://docs.djangoproject.com/fr/dev/topics/http/urls/# reverse) au lieu de référencer l'URL '/ orders /' directement dans votre 'HttpResponseRedirect' ... cela vous évitera des tonnes de maux de tête s dans le futur, croyez-moi :) – sdolan

+0

Ha! Vous avez raison, j'aurais dû le faire plus tôt. –

Répondre

7

save() doit renvoyer l'instance nouvellement créée.

if contractor_form.is_valid(): 
    instance = contractor_form.save() 
    parameters['contractor'] = instance 

où id serait instance.id, ou mieux encore instance.pk.

pk vs. id:

Peu importe si vous définissez un clé primaire vous, ou laissez Django fournir pour vous, chaque modèle aura une propriété appelée pk. Il se comporte comme un attribut normal sur le modèle , mais est en réalité un alias pour , quel que soit l'attribut est le champ clé primaire pour le modèle. Vous pouvez lire et définir cette valeur, tout comme vous le feriez pour tout autre attribut, et mettre à jour le champ correct dans le modèle.

Suivi commentaire:

Eh bien, il fonctionne par défaut, donc il doit y avoir quelque chose d'autre mal.

modèles.py

class Category(models.Model): 
    name = models.CharField(max_length=70) 
    slug = models.SlugField() 

forms.py

from django import forms 
from models import Category 

class MyModelForm(forms.ModelForm): 
    class Meta: 
     model = Category 

test dans la coquille:

In [3]: from katalog.forms import MyModelForm 
In [4]: data = {'name':'Test', 'slug':'test'} 
In [5]: form = MyModelForm(data) 
In [6]: instance = form.save() 
In [7]: instance 
Out[7]: <Category: Test> 
In [8]: instance.id 
Out[8]: 5L 
+0

C'était ma première estimation, mais malheureusement, cela ne fonctionne pas comme ça. ModelForm.save() renvoie None. Il devrait y avoir un moyen de le faire avec la méthode save() surchargée, mais cela semble trop compliqué et désordonné. –

+0

Pouvez-vous nous montrer votre code ModelForm 'entrepreneur' alors? –

+0

Eh bien, j'ai encore testé cela, et votre solution fonctionne. Je vais cependant le tester plus en profondeur avec mon cas spécifique. –

Questions connexes