[Django]-Sending mail with an absolute_uri when a model is created (without a request object)

2đź‘Ť

âś…

Is there a way to use the sites framework to return the true absolute URL, like request.build_absolute_uri() does?

The problem is that, in general, there isn’t a true absolute URL. Django can work just fine without a web server at all, generating emails, saving models (and triggering the post-save signal), etc. And if there is a web server there’s no way for Django to know what domain names it’s servicing, which is why you need a request object and why you need settings like ALLOWED_HOSTS, etc.

The general way you would handle this is by explicitly telling Django what site it is serving. For example, you would have a different settings file for each distribution and each of those files would indicate what domain name it should use (via the SITE_ID setting, if you’re using the sites framework; or else you could state it explicitly with your own setting). Using different settings files for different servers is common practice.

Now, in your particular case it sounds like the save is being triggered from inside a web request (via the admin?), so if you could get ahold of that request you could then use its domain name to construct your link. Django doesn’t include any way to for you get that request except by being passed it as an argument. You’re not the first to want this, though, so if you search for “Django global request” you can see how others have approached the problem. This article, for example, presents a couple ideas, and this app is designed to “give access to Django’s HTTPRequest object whenever is needed, without explicitly passing it down the path of code”.

Leave a comment