Relative links to admin.py

There is a class in admin.py:

class NewsAdmin(TranslationAdmin):
    form = NewsForm
    list_display = ('title', 'date' 'show_url')
    
    def show_url(self, obj):
        return format_html("<a href='http://www.host.ru/news/{url}' target='_blank'>view</a>", url=obj.id)
        
    show_url.short_description = "View"

Need a link http://www.host.ru replace with a relative one, something like this: protocol + domain name + news/{url} How can this be done?

I think you are better off making it hardcoded value in your settings, like BASEURL = 'http://www.host.ru'
then having different settings.py for production and development (dev with BASEURL = 'https://localhost:8080' for testing)

and then you can fetch it with:


def show_url(self, obj):
    from django.conf import settings
    return format_html("<a href='{base}/news/{url}' target='_blank'>view</a>", base=settings.BASEURL, url=obj.id)

# or use reverse so it's dynamically linked to your urls.py (this is what I do)
def show_url_with_reverse(self, obj):
    from django.conf import settings
    from django.urls import reverse
    return format_html("<a href='{base}{url}' target='_blank'>view</a>",
        base=settings.BASEURL,
        url=reverse('myviewname', args=[obj.id])
        )

This isn't the answer you wanted, but I'm throwing it in as a way. I hope someone smarter than me has found a better way, but this is a fallback.


Reasoning

This is all moot because you don't have access to the request object inside that method.
I've found that you need the request object to dynamically get the host, the www.host.ru part, with request.get_host().
But that still leads the http:// and https://, which is not available anywhere (that I've found), so I have that hardcoded in my settings.py.

So either way something will have have to be hardcoded, so might as well be the entire url. It's gross, I hate it, but w/e it gets the job done

Back to Top