2010-01-10 13 views
2

Je sais que je peux transmettre des valeurs d'objet via un modèle d'URL et les utiliser dans les fonctions de vue. Par exemple:Transmission de données d'objet via l'URL

(r'^edit/(?P<id>\w+)/', edit_entry), 

peut être utilisé comme:

def edit_entry(request, id): 
     if request.method == 'POST': 
       a=Entry.objects.get(pk=id) 
       form = EntryForm(request.POST, instance=a) 
       if form.is_valid(): 
         form.save() 
         return HttpResponseRedirect('/contact/display/%s/' % id) 
     else: 
       a=Entry.objects.get(pk=id) 
       form = EntryForm(instance=a) 
     return render_to_response('edit_contact.html', {'form': form}) 

Mais comment puis-je passer une valeur d'un champ de modèle (autre que « id ») dans l'URL? Par exemple, j'ai un modèle de base abstrait avec un champ "job_number" qui est partagé par les modèles enfants "OrderForm" et "SpecReport". Je veux cliquer sur "job_number" sur le bon de commande et appeler le rapport de spécifications pour ce même numéro de job. Je peux créer un

href="/../specifications/{{ record.job_number }} 

passer l'info à l'URL, mais je sais déjà que cette syntaxe regex est incorrecte:

(r'^specifications/(?P<**job_number**>\w+)/', display_specs), 

et je ne peux saisir l'job_number dans la vue de la même façon que je pourrait un id:

def display_specs(request, job_number): 
    records = SpecReport.objects.filter(pk=job_number) 
    tpl = 'display.html' 
    return render_to_response(tpl, {'records': records }) 

y at-il une approche facile à ceci ou est-il plus compliqué que je pense qu'il est?

le code modifié est la suivante:

(r'^specdisplay/?agencyID=12/', display_specs), 

et:

def display_specs(request, agencyID): 
    agencyID= request.GET.get('agencyID') 
    records = ProductionSpecs.objects.filter(pk=id) 
    tpl = 'display_specs.html' 
    return render_to_response(tpl, {'records': records }) 

ne sais pas comment filtrer. pk n'est plus applicable.

+0

Je pense que votre seul problème restant est le regex url :) tout après le point d'interrogation (y compris) doit aller. Ceux-ci sont appelés paramètres GET et ne font pas partie des éléments correspondants. –

Répondre

6

Oui, vous faites cela un peu plus compliqué que ce soit.

Dans votre urls.py vous avez:

(r'^edit/(?P<id>\w+)/', edit_entry), 

Maintenant, il vous suffit d'ajouter l'expression presque identique pour display_specs:

(r'^specifications/(?P<job_number>\w+)/', display_specs), 

Parenthèses dans le regex identifie un groupe et le (?P<name>...) définit un groupe nommé qui sera nommé name. Ce nom est le paramètre à votre vue.

Ainsi, votre point de vue ressemblera maintenant à:

def display_specs(request, job_number): 
    ... 

Enfin, même si cela va fonctionner, lorsque vous redirigez à la vue, au lieu d'utiliser:

HttpResponseRedirect('/path/to/view/%s/' % job_number) 

Utilisez le plus DRY :

HttpResponseRedirect(
    reverse('display_specs', kwargs={'job_number': a.job_number})) 

Maintenant, si vous décidez de modifier vos chemins de ressources, votre redirection ne sera pas modifiée. ak.

Pour que cela fonctionne, vous devez commencer à utiliser named urls dans votre URLconf comme ceci:

url(r'^specifications/(?P<job_number>\w+)/', display_specs, name='display_specs'), 
+0

J'ai essayé ceci en premier. Mais django renvoie une erreur 404. Si le "agencyID" est "EMP-INT-37914" et l'url est écrit (r '^ specdisplay/(? P \ w +) /', display_specs), - Django dit: Demande d'URL: \t http: // localhost : 8000/specdisplay/EMP-INT-37914/ essayé les urls suivantes: ^ specdisplay// ... ce pourquoi je suppose que vous ne pouviez pas écrire l'expression de la même façon (P \ w +?) comme . – kjarsenal

+0

Il est vrai que je ne comprends pas les groupes nommés aussi bien que je le voudrais (je travaille dessus). Mais il semble que le cœur de ce problème est que cette syntaxe "(? P \ w +)" ne fonctionne que lorsque les données à l'intérieur des accolades d'angle est au format entier? Lorsque mes ID d'agence sont des données de chaîne (comme toutes les miennes), django a jeté des erreurs. La seule chose que je pouvais penser était différente de était chaîne vs entier.Quand j'ai changé "EMP-INT-37914" en "5", ça a marché comme un charme. Malheureusement, cela ne m'aide pas car mes données agencyID sont des données string et je n'arrive toujours pas à comprendre comment les transmettre. – kjarsenal

+0

Le motif '\ w' signifie tout caractère alphanumérique et trait de soulignement, c'est-à-dire [a-zA-Z0-9_]. Essayez ce modèle:/(? P [A-Z0-9 -] +)/ou peut-être (en supposant que les spécifications d'affichage commencent toujours par EMP-INT)/(? P EMP-INT- \ d +)/ –

1

Ne sachant pas à quoi ressemble la structure de votre modèle ... pourquoi ne pourriez-vous pas simplement passer l'ID du travail particulier et le récupérer avec une requête? Afaik chaque modèle a automatiquement un champ id qui s'auto-incrémenté et est un identifiant unique d'une ligne (un index si vous voulez), il suffit donc de changer la création de href en {{record.id}} et de partir de là.

Essayez de passer le job_number à travers l'URL puis, surtout si vous ne se soucie pas assez url de trop faire:

url: /foo/bar/?job_number=12 

sans majoration spéciale pour attraper ce BTW, la regex est r^foo/bar/»

Et puis le lire dans la vue comme ceci:

job_number= request.GET.get('job_number') 
+0

Parce que l'ID de l'objet OrderForm ne sera pas nécessairement le même que l'ID de l'objet SpecForm. Si j'ai des formulaires de commande pour chaque travail - mais des formulaires de spécification pour seulement quelques travaux, je ne pense pas que je peux être sûr que les identifications seront toujours les mêmes. Mais le nombre d'emplois le sera toujours. C'était ma logique de toute façon. Peut-être tort. Je vais essayer la route d'identification et voir si cela fonctionne. – kjarsenal

+0

parce que je ne pouvais pas rendre ce commentaire assez lisible, j'ai édité la réponse, j'espère que c'est bien –

+0

merci pour l'aide. J'ai essayé de modifier le code en fonction de vos conseils. Toujours pas tout à fait là. Pouvez-vous jeter un coup d'œil au code modifié ci-dessus et me dire si je suis sur la bonne voie? Merci. Remplacer également "job_number" par "agencyID" car il s'agit du nom réel des champs. – kjarsenal

0

Je ne comprends vraiment pas votre question. Quelle est la différence entre passer id et passer job_number dans une URL? Si vous pouvez en faire un, pourquoi ne pouvez-vous pas faire l'autre? Et une fois que le job_number est en vue, pourquoi ne pouvez pas vous faire un filtre normal:

records = SpecReport.objects.filter(job_number=job_number) 
+0

ok, donc je filtre maintenant de cette façon. Je vous remercie. – kjarsenal

+0

Il semble y avoir une différence si job_number n'est pas un nombre autant qu'un code (comme "EMP-AS-15751"), qui est malheureusement la façon dont beaucoup d'entreprises identifient leurs produits. Je ne pense pas que je ne peux pas passer l'info - c'est juste que je ne pense pas que je peux utiliser la même regex que pour . – kjarsenal