Get current site inside model

141 views
Skip to first unread message

Max

unread,
Jan 13, 2017, 1:06:48 PM1/13/17
to Django users
Hi, guys. I want to get absolute url for Model with domain based on request (there is not SITE_ID in the settings.py). How?


Vijay Khemlani

unread,
Jan 13, 2017, 3:09:31 PM1/13/17
to django...@googlegroups.com
You would need to pass it as argument, or set a default Site,
otherwise it doesn't make sense

For example, when calling the method from the shell (not a web
request) what will you expect it to return?

On 1/13/17, Max <kisel...@gmail.com> wrote:
> Hi, guys. I want to get absolute url for Model with domain based on request
>
> (there is not SITE_ID in the settings.py). How?
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/ae4a2205-209f-46a5-a60d-4fcd208f2a49%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

Max

unread,
Jan 13, 2017, 4:15:43 PM1/13/17
to Django users
Vijay Khemlani, i think my question have not a lot of details. More
1) Django site framework (works with request.get_host() without Site_id).
I can get the current site with Site.objects.get_current(request), shortcuts (get_current_site) or through model. But i have only one model with site relationship.

2) Django class-based view.

3) For example, template
{{obj.get_url}} <- error Site does not exists [set site_id or use 1)]

Model
class Model(models.Model):
      def get_absolute_url(self):
    return 'http://{}{}'.format(Site.objects.get_current(????).domain,
reverse(
viewname='product',
args=[self.slug]))

Thanks, also i do not want to change site_id dynamically (thread) or use site through model-model.

Vijay Khemlani

unread,
Jan 13, 2017, 5:00:41 PM1/13/17
to django...@googlegroups.com
Once again, if you don't have a default site_id or the request object
available inside the method, then what do you expect it to return? I'm
not asking programatically, but logically,

If you only care about the template the you can concatenate the domain
and the absolute path in the template itself

{{ domain }}{{ ob.get_absolute url }}

where the absolute url is something like '/model/5' or something like
that, without the domain.



On 1/13/17, Max <kisel...@gmail.com> wrote:
> Vijay Khemlani, i think my question have not a lot of details. More
> 1) Django site framework (works with request.get_host() without Site_id).
> I can get the current site with Site.objects.get_current(*request*),
> shortcuts (get_current_site) or through model. But i have only one model
> with site relationship.
>
> 2) Django class-based view.
>
> 3) For example, template
>
>> {{obj.get_url}} <- error Site does not exists [set site_id or use 1)]
>
>
> Model
> class Model(models.Model):
> def get_absolute_url(self):
>
> return 'http://{}{}'.format(Site.objects.get_current(????).domain,
> reverse(viewname='product',
> args=[self.slug]))
>
>
> Thanks, also i do not want to change site_id dynamically (thread) or use
> site through model-model.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/32ee2f28-8d2b-4a14-ba87-c6150fd88399%40googlegroups.com.

Max

unread,
Jan 13, 2017, 5:18:03 PM1/13/17
to Django users
{{ domain }}{{ ob.get_absolute url }} - is not cool , i set site with context proccesor for domain


Once again, if you don't have a default site_id or the request object 
available inside the method, then what do you expect it to return? I'm 
not asking programatically, but logically,  

if site_id is enabled, django is not use site by request.

So, can i get request obj inside model? Is not true MVC pattern, but in docs i cannot change runtime settings(not recommended)

 

Vijay Khemlani

unread,
Jan 13, 2017, 5:33:37 PM1/13/17
to django...@googlegroups.com
I'm not gonna start on the "cool" part

You could generate the urls on the view and pass them already
generated to the template

On 1/13/17, Max <kisel...@gmail.com> wrote:
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/0b7653e3-0b93-4f09-81eb-51d23216dec5%40googlegroups.com.

Max

unread,
Jan 13, 2017, 5:48:23 PM1/13/17
to Django users
For example, also i can change queryset with "fake site" listview -> request -> set queryset site -> template. maybe it will be work, but also i use rss/sitemaps. they will not use abs path, because based on Model.

You could generate the urls on the view and pass them already
generated to the template


I thought about it.

Melvyn Sopacua

unread,
Jan 14, 2017, 11:01:09 AM1/14/17
to django...@googlegroups.com

On Friday 13 January 2017 13:15:43 Max wrote:

> Vijay Khemlani, i think my question have not a lot of details. More

> 1) Django site framework (works with request.get_host() without

> Site_id). I can get the current site with

> Site.objects.get_current(*request*), shortcuts (get_current_site) or

> through model. But i have only one model with site relationship.

>

> 2) Django class-based view.

>

> 3) For example, template

>

> > {{obj.get_url}} <- error Site does not exists [set site_id or use

> > 1)]

>

> Model

> class Model(models.Model):

> def get_absolute_url(self):

>

> return 'http://{}{}'.format(Site.objects.get_current(????).domain,

> reverse(viewname='product',

> args=[self.slug]))

>

>

> Thanks, also i do not want to change site_id dynamically (thread) or

> use site through model-model.

 

I wrote this a long time ago. Maybe it's what you need:

from django.conf import settings

from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.db import models

 

class PublicModel(models.Model):
"""A model that has a place on the site.

Specifically, this adds the following method to the model:
- get_absolute_url(): the url from the base of the site to the detail view
of the model. It is implemented as the get_absolute_url() method so
that the Django admin will provide a "View on site" link.
The default implementation returns the url associated with:
appname.views.modelname
and is decorated with the permalink decorator.
Additionally the following property is added (implemented as a getter and
setter):
- fully_qualified_url: A url that specifies the server and protocol as well
as the absolute url. It is intended to be used for:
- out of band communications like email;
- setting or changing the protocol security;
- changing or setting the associated site;
The general purpose of the model is to make it easier to get this
information in a template and handle it in a view.
"""
_site_id = None
_protocol = None

@models.permalink
def get_absolute_url(self):
model_name = self._meta.object_name.lower()
viewname = '{}_detail'.format(model_name)
return viewname, [str(self.pk)]

absolute_url = property(get_absolute_url, doc="Absolute url")

def get_fully_qualified_url(self):
site_id = self._site_id or getattr(settings, 'SITE_ID', 1)
protocol = self._protocol or 'http'
try:
site = Site.objects.get(pk=site_id)
except Site.DoesNotExist:
raise ImproperlyConfigured(
'Site with id {} does not exist'.format(site_id))
url = '{}://{}{}'.format(protocol, site.domain, self.absolute_url)
return url

def set_fully_qualified_url(self, protocol, site_id_or_obj=None):
if site_id_or_obj is None:
site_id = self._site_id or getattr(settings, 'SITE_ID', 1)
site = Site.objects.get(pk=site_id)
elif isinstance(site_id_or_obj, Site):
site = site_id_or_obj
else:
site = Site.objects.get(pk=site_id_or_obj)
self._site_id = site.pk
self._protocol = protocol

fully_qualified_url = property(
get_fully_qualified_url, set_fully_qualified_url,
doc="Fully qualified url (includes protocol and domain)"
)

def get_list_url(self):
viewname = '{}_list'.format(self._meta.object_name.lower())
return reverse(viewname)

@classmethod
def set_site_for_model(cls, site_id_or_obj):
if isinstance(site_id_or_obj, Site):
cls._site_id = site_id_or_obj.pk
else:
cls._site_id = site_id_or_obj

@classmethod
def set_protocol_for_model(cls, protocol):
cls._protocol = protocol

class Meta:
abstract = True

--

Melvyn Sopacua

Max

unread,
Jan 14, 2017, 7:00:32 PM1/14/17
to Django users
Melvyn Sopacua, i will look it.
Thank you all.
Reply all
Reply to author
Forward
0 new messages