Search code examples
djangourlcron

How can I get the URL (with protocol and domain) in Django (without request)?


I want to send mails in a cron job. The mail should contain a link to my application.

In cron job, I don't have a request object, and can't use request.build_absolute_uri().

AFAIK the site framework can help here. But does not give me the protocol (http vs https)?

My application is reusable and sometimes gets hosted on http and sometimes on https sites.

Update

I search a common django way. Creating custom settings is possible, but a solution with django standards is preferred.


Solution

  • There's special standard module for this task - Sites Framework. It adds Site model, which describes specific site. This model has field domain for domain of the project, and a name - human-readable name of the site.

    You associate your models with sites. Like so:

    from django.db import models
    from django.contrib.sites.models import Site
    
    class Article(models.Model):
        headline = models.CharField(max_length=200)
        # ...
        site = models.ForeignKey(Site, on_delete=models.CASCADE)
    

    When you need to make an url for the object you may use something like the following code:

       >>> from django.contrib.sites.models import Site
       >>> obj = MyModel.objects.get(id=3)
       >>> obj.get_absolute_url()
       '/mymodel/objects/3/'
       >>> Site.objects.get_current().domain
       'example.com'
       >>> 'https://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url())
       'https://example.com/mymodel/objects/3/'
    

    This way you can have multiple domains and content spread between them. Even if you have only one domain I recommend use it to achieve a good standard comfortable way to keep domain settings.

    Installatioin is quite easy:

    1. Add 'django.contrib.sites' to your INSTALLED_APPS setting.

    2. Define a SITE_ID setting:

       SITE_ID = 1
      
    3. Run migrate.