10

I want to have a absolute/complete url when i call my models get_absolute_url method in template. in my entry model i have below:

def get_absolute_url(self): return ('blog_entry_detail', (), { 'year': self.pub_date.strftime("%Y"), 'month': self.pub_date.strftime("%b").lower(), 'day': self.pub_date.strftime("%d"), 'slug': self.slug }) get_absolute_url = models.permalink(get_absolute_url) 

in my template file:

{{object.get_absolute_url}} 

I want to output the url prepended with 'http://www.example.com'

I want to use below lines to get the current domain name but i dont know where will i put it.

from django.contrib.sites.models import Site current_site = Site.objects.get_current().domain 
1
  • 1
    There's a good answer to this question here, which you might adapt to provide a method on your model (note that you might need to pass the request object to the template as extra context): stackoverflow.com/questions/2345708/… Commented Sep 12, 2012 at 4:25

4 Answers 4

4

This might work for you:

class Article(models.Model): ... ... def get_absolute_url(self): path = reverse('display_article', args=[self.slug]) return "http://%s%s" % (self.site, path) 
Sign up to request clarification or add additional context in comments.

3 Comments

Still sucks that it doesn't auto-detect the protocol for you. You'd think at least the RequestSite object would know that!
How are you dealing with port ? Development server run on 8000 (default, but you might set another one), as production runs probably default 80 or 443 (and unmentioned in URL).
self does not have site now! Django 2.1
3

My solution, with Sites framework

In API\views.py

class NotificationSerializer(serializers.HyperlinkedModelSerializer): absolute_url = serializers.CharField(source='get_full_absolute_url', read_only=True) class Meta: model = Notification fields = ( 'id', 'created_at', 'msg_txt', 'url', 'absolute_url' ) 

In models.py

from django.contrib.sites.models import Site class Notification(models.Model): sender_user = models.ForeignKey(User, related_name = 'sender_user' ) created_at = models.DateTimeField(default=timezone.now) reciever_user = models.ForeignKey(User, related_name = 'reciever_user') readed_at = models.DateTimeField( blank=True, null = True ) msg_txt = models.CharField(max_length=255, blank=False) def get_absolute_url(self): return "/notification/%i/" % self.id def get_full_absolute_url(self): domain=Site.objects.get_current().domain return 'http://%s%s' % (domain, self.get_absolute_url()) 

Var 2, without Sites framework

If you have not Sites framework, you can use the ALLOWED_HOSTS settings.

In models.py

from myapp.settings import ALLOWED_HOSTS class Notification(models.Model): ... def get_full_absolute_url(self): domain=ALLOWED_HOSTS[0] return 'http://%s%s' % (domain, self.get_absolute_url()) 

ALLOWED_HOSTS is required for production site.

1 Comment

How to deal with port ? Development server run on 8000 (default, but you might run it over another one), as production runs probably default (and unmentioned in URL) 80 or 443.
1

When I need full URLs, I usally go for request.get_absolute_url(), rather than assemble it myself using Site.objects.get_current().domain. However, there seem to be some issues with this method.

In any case, I don't think the model is the right place to put this because it violates the DRY principle by duplicating the URL in the urlconf and in the model. Can you not use some form of reverse URL lookups?

2 Comments

can you pls give some example on how to use request.get_absolute_url()? currently i have a context processor to pass the site name variable to templates and assemble the absolute url like this: <a href="{{SITE_DOMAIN}}{{object.get_absolute_url}}">{{object.title}}</a> which i think is not a good way to output the absolute url
Just pass the URL relative to your root URL confirm like 'request.get_full_url(URL_to_my_view)'. I often use that along with the reverse lookup, which is also why I links to that.
0

As I didn't find any up-to-date answer on this, I achieved the results by this:

In settings.py, I set BASE_URL and then in models get_absolute_url method:

def get_absolute_url(self): from django.urls import reverse from django.conf import settings path = reverse('urlname', args=(arg)) # Assuming that a URL with name `urlname` is set in urls.py return '{}{}'.format(settings.BASE_URL, path) 

I don't know either this is the best way to get the full URL or not, but I didn't find any better way to achieve the desired results. I hope this helps someone.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.