5👍
✅
Move the import from the top of
The error occurs because when you import get_top_viewed_posts
at the top of models.py
the Post
model is not declared yet.
You have a few alternatives.
Move the import from the top of models.py
to inside the method
def send(self):
from social.services import get_top_viewed_posts
posts = get_top_viewed_posts()
Don’t worry about performance, imports are cached – but if you use it in other methods it may be tedious to repeat the same import over and over.
Abstract the class
Make the function more generic passing the model as an argument, this way you don’t need to import the model in the top of the services.py
file:
def get_top_viewed_model(model, popular_ids, order_by='-created_at'):
return model.objects..filter(
pk__in=popular_ids,
).order_by(
order
)
Then:
def send(self):
posts = get_top_viewed_model(type(self), popular_posts_ids)
# at other places
get_top_viewed_model(Posts, popular_posts_ids)
Use a custom manager
Create a custom manager with a top_viewed
method:
class TopViewedManager(models.Manager):
def __init__(self, order='-created_at', **kwargs):
self._order = order
self._filter = kwargs
def top_viewed(self):
return self.get_queryset().filter(**self._filter).order_by(self._order)
class Post(models.Model):
...
objects = TopViewedManager(pk__in=popular_posts_ids)
Then just use this where you would use get_top_viewed_model
:
Post.objects.top_viewed()
This manager is quite generic so you can use it with any model, filter and order you want.
Probably there are other alternatives and it is a matter of personal taste.
Source:stackexchange.com