djangocms_blog/djangocms_blog/managers.py

128 lines
5 KiB
Python
Raw Normal View History

2014-01-04 17:07:09 +01:00
# -*- coding: utf-8 -*-
from collections import Counter
import datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _
from parler.managers import TranslationManager
2014-01-04 17:07:09 +01:00
from .settings import BLOG_TAGCLOUD_MIN, BLOG_TAGCLOUD_MAX
class TaggedFilterItem(object):
def tagged(self, other_model=None, queryset=None):
"""
Restituisce una queryset di elementi del model taggati,
o con gli stessi tag di un model o un queryset
"""
tags = self._taglist(other_model, queryset)
return self.get_query_set().filter(taglist__in=tags)
def _taglist(self, other_model=None, queryset=None):
"""
Restituisce una lista di id di tag comuni al model corrente e al model
o queryset passati come argomento
"""
from taggit.models import TaggedItem
filtro = None
if queryset is not None:
filtro = set()
for item in queryset.all():
filtro.update(item.tags.all())
filtro = set([tag.id for tag in filtro])
elif other_model is not None:
filtro = set(TaggedItem.objects.filter(content_type__model=other_model.__name__.lower()).values_list('tag_id', flat=True))
tags = set(TaggedItem.objects.filter(content_type__model=self.model.__name__.lower()).values_list('tag_id', flat=True))
if filtro is not None:
tags = tags.intersection(filtro)
return list(tags)
def tag_list(self, other_model=None, queryset=None):
"""
Restituisce un queryset di tag comuni al model corrente e
al model o queryset passati come argomento
"""
from taggit.models import Tag
return Tag.objects.filter(id__in=self._taglist(other_model, queryset))
def tag_list_slug(self, other_model=None, queryset=None):
qs = self.tag_list(other_model, queryset)
return qs.values("slug")
def tag_cloud(self, other_model=None, queryset=None, published=True):
2014-01-04 17:07:09 +01:00
from taggit.models import TaggedItem
tag_ids = self._taglist(other_model, queryset)
kwargs = {}
if published:
kwargs = TaggedItem.bulk_lookup_kwargs(self.model.objects.published())
kwargs['tag_id__in'] = tag_ids
counted_tags = dict(TaggedItem.objects
.filter(**kwargs)
.values('tag')
.annotate(count=models.Count('tag'))
.values_list('tag', 'count'))
tags = TaggedItem.tag_model().objects.filter(pk__in=counted_tags.keys())
for tag in tags:
tag.count = counted_tags[tag.pk]
return sorted(tags, key=lambda x: -x.count)
2014-01-04 17:07:09 +01:00
class GenericDateTaggedManager(TaggedFilterItem, TranslationManager):
use_for_related_fields = True
start_date_field = "date_published"
end_date_field = "date_published_end"
publish_field = "publish"
def published(self, qs=None):
qs = self.published_future(qs)
if self.start_date_field:
return qs.filter(
**{"%s__lte" % self.start_date_field: datetime.datetime.now()})
else:
return qs
def published_future(self, qs=None):
if not qs:
qs = self.get_query_set().all()
if self.end_date_field:
qfilter = (
models.Q(**{"%s__gte" % self.end_date_field: datetime.datetime.now()})
| models.Q(**{"%s__isnull" % self.end_date_field: True})
)
qs = qs.filter(qfilter)
return qs.filter(**{self.publish_field: True})
def archived(self, qs=None):
if not qs:
qs = self.get_query_set().all()
if self.end_date_field:
qfilter = (
models.Q(**{"%s__lte" % self.end_date_field: datetime.datetime.now()})
| models.Q(**{"%s__isnull" % self.end_date_field: False})
)
qs = qs.filter(qfilter)
return qs.filter(**{self.publish_field: True})
def available(self, qs=None):
if not qs:
qs = self.get_query_set().all()
return qs.filter(**{self.publish_field: True})
def filter_by_language(self, language):
qs = self.get_query_set()
return qs.filter(models.Q(language__isnull=True) | models.Q(language=language))
def get_months(self, queryset=None):
"""Get months with aggregatet count (how much posts is in the month). Results are ordered by date."""
# done via naive way as django's having tough time while aggregating on date fields
if not queryset:
queryset = self.get_query_set()
dates = queryset.values_list(self.start_date_field, flat=True)
dates = [(x.year, x.month) for x in dates]
date_counter = Counter(dates)
dates = set(dates)
dates = sorted(dates, reverse=True)
return [{'date': datetime.date(year=year, month=month, day=1),
'count': date_counter[year, month]} for year, month in dates]