Malik A. Rumi
Malik A. Rumi

Reputation: 2015

get_absolute_url and reverse outside of templates

"...If you need to use something similar to the url template tag in your code, Django provides the following function: reverse()...."

I looked at the docs for get_absolute_url() and reverse, as well as the example given:

a href="{{ object.get_absolute_url }}">{{ object.name }} /a>

What I am not seeing, or understanding, is how are we passing the kwargs (name, self, ID, whatever) to the model method so it knows which one of 100 instances to return the url for, particularly where I need to use it in text, outside the template system?

a href="name_of_object.get_absolute_url ">text name of object

  1. Do I have to put the full name of the object in the href?
  2. How would I use a variable like self or object or modelname instead?
  3. Can I rewrite gau to take kwargs as well as self?
  4. If I do that, can I put the () on the end of gau to take in the kwargs? We can’t do that in the template.
  5. Can I use:

a href="self.get_absolute_url(**kwargs) ">text name of object ?

or

a href="object.get_absolute_url(self, **kwargs) ">text name of object ?

  1. And if so, do I need to add anything to the definition of gau on my model to make sure those kwargs are passed to return?

  2. Or do I just treat it like a regular outside link, and thus have to hard code it?

Thanks. --update--

@ChidG: Thanks for such a complete answer, and my apologies for taking so long to get back to you. I'd like to clarify my use case a little, and see if that changes your answer any. If I have ten articles using the same template, each article is still unique, and their links to different urls are not going to be in the same place on each article. So there is no way for me to put a single (or multiple) url tag in the template that will be useful to all ten articles. That's what I meant by using gau / the url tag outside the template. I want to do a simple search and replace that will turn the affected text into links. Otherwise, I'd have to do them one at a time by hand, which I assumed couldn't be the way this has to be done. What am I missing?

Upvotes: 0

Views: 578

Answers (1)

ChidG
ChidG

Reputation: 3223

When Django's docs say 'outside of the template system', they mean in Python code, in a views.py or models.py (or whatever.py) file. The examples you have given all appear to be HTML (they feature a tags, so it looks like you are talking about HTML).

If it's HTML, then it's not outside the template system, so the Python functions you've mentioned won't work. You need to use the Django template tags.

Regarding this question:

What I am not seeing, or understanding, is how are we passing the kwargs (name, self, ID, whatever) to the model method so it knows which one of 100 instances to return the url for, particularly where I need to use it in text, outside the template system?

{{object.get_absolute_url}} (or object.get_absolute_url() in pure Python) does not require a kwarg, because the get_absolute_url method on the model already knows how to generate the correct URL with whatever kwargs are needed. If it doesn't already know how to do that (because of your specific URL configuration), you can write a custom get_absolute_url method which will enable that.

Whenever you return an HTML file from a Django view (unless you're doing something unconventional), you are using the template system. When you're using the template system, you reference Django context variables using {{ }} and custom tags using {% %}. So to insert a URL into a template, whether it's into an a tag or just into the text, you will use curly brackets and it will be {{ object.get_absolute_url }} or using the url tag itself, {% url 'whatever_url_name' kwarg=value %}

  1. Do I have to put the full name of the object in the href?

You have to put whatever the context variable is that refers to the object in the template context.

  1. How would I use a variable like self or object or modelname instead?

You can use whatever name you like for the context variable. If you're using Django's class based views it will be object by default for a single object view, but you can change it to whatever you like using the context_object_name attribute on the view.

  1. Can I rewrite gau to take kwargs as well as self?

That is unnecessary. get_absolute_url returns a full URL, and all it needs is the model instance. The model instance must be able to find its own url using its own get_absolute_url method without any further kwargs.

  1. Can I use:

The correct syntax is clearly demonstrated in the Django docs for get_absolute_url that you've linked to:

<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>

Upvotes: 1

Related Questions