2

I know that I can pass object values through a URL pattern and use them in view functions. For instance:

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

can be utilized like:

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})

But how do I pass a value from a model field (other than "id") in the url? For instance, I have an abstract base model with a field "job_number" that is shared by child models "OrderForm" and "SpecReport". I want to click on the "job_number" on the order form and call the Spec Report for that same job number. I can create an

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

to pass the info to the url, but I already know that this regex syntax is incorrect:

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

nor can I capture the job_number in the view the same way I could an id:

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

Is there an easy approach to this or is it more complicated than I think it is?

the amended code is as follows:

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

and:

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 })

not sure how to filter. pk is no longer applicable.

1
  • I think your only remaining problem is the url regex :) everything after the question mark (inclusive) has to go. Those are called GET parameters and aren't part of the matching stuff. Commented Jan 10, 2010 at 22:17

3 Answers 3

6

Yes, you are making this a little more complicated that it is.

In your urls.py you have:

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

Now you just need to add the almost identical expression for display_specs:

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

Parenthesis in the regex identifies a group and the (?P<name>...) defines a named group which will be named name. This name is the parameter to your view.

Thus, your view will now look like:

def display_specs(request, job_number):
   ...

Finally, even though this will work, when you redirect to the view, instead of using:

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

Use the more DRY:

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

Now if you decide to change your resource paths your redirect won't break.

For this to work you need to start using named urls in your urlconf like this:

url(r'^specifications/(?P<job_number>\w+)/', display_specs, name='display_specs'),
Sign up to request clarification or add additional context in comments.

4 Comments

I tried this first. But django throws an 404 error. If the "agencyID" is "EMP-INT-37914" and the url is written (r'^specdisplay/(?P<agencyID>\w+)/', display_specs), — Django says :Request URL: localhost:8000/specdisplay/EMP-INT-37914 Tried the following urls: ^specdisplay/(?P<agencyID>\w+)/ ... this is why I assumed you couldn't write the expression the same way as <id>.
It's true that I don't understand named groups as well as I'd like (I'm working on it). But it seems that the crux of this problem is that this syntax "(?P<whatever>\w+)" only works when the data inside the angle braces is in integer format? When my agencyIDs are string data (as all of mine are) django threw errors. The only thing I could think that was different than <id> was string vs integer. When I changed "EMP-INT-37914" to "5", it worked like a charm. Unfortunately, it doesn't help me because my agencyID data is string data and I still can't figure out how to pass it.
The pattern '\w' means any alphanumeric character and underscore, i.e. [a-zA-Z0-9_]. Try this pattern: /(?P<job_number>[A-Z0-9-]+)/ or maybe (assuming display specs always start with EMP-INT) /(?P<job_number>EMP-INT-\d+)/
1

Not knowing what your model structure is like ... why couldn't you just pass the particular job's id and then pick it up with a query?

Afaik every model automatically has an id field that autoincrements and is a unique identifier of a row (an index if you will), so just change the href creation to {{record.id}} and go from there.

Try passing the job_number through the url then, especially if you don't care about pretty url's too much just do this:

url:  /foo/bar/?job_number=12

no special markup to catch this btw, the regex is r'^foo/bar/'

And then read it in the view like this:

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

3 Comments

Because the id for the OrderForm object will not necessarily be the same as the id for the SpecForm object. If I have order forms for every job - but spec forms for only some jobs, I don't think I can be sure that the ids will always match. But the job numbers always will. That was my logic anyway. Could be wrong. I'll try the id route and see if it works.
because I couldn't make this comment readable enough, I've edited the answer, hope that's alright
thanks for the help. I tried to amend the code with respect to your advice. Still not quite there. Can you take a quick look at the amended code above and tell me if I'm on the right track? Thanks. Also- replacing "job_number" with "agencyID" as this is the fields actual name.
1

I really don't understand your question. What's the difference between passing id and passing job_number in a URL? If you can do one, why can't you do the other? And once the job_number is in the view, why can't you do a normal filter:

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

1 Comment

There seems to be a difference if job_number is actually not a number so much as a code (like "EMP-AS-15751"), which unfortunately is the way that a lot of businesses identify their products. I don't think it's that I can't pass the info – it's just that I don't think I can use the same regex as for <id>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.