You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
4.5 KiB
Python

from django.db import models
from django.db.models.aggregates import Sum
from django.db.models.functions import Coalesce
from django.conf import settings
from django.urls import reverse
from django.template.loader import render_to_string
from django.dispatch import receiver
from django.utils.translation import get_language
from constance import config
from tinymce import HTMLField
def get_internationalized(obj_set, prop_name):
obj = obj_set.filter(language=get_language()).first()
if obj:
return getattr(obj, prop_name)
return ""
class KbCategory(models.Model):
slug = models.SlugField()
internal_name = models.CharField("Internal name", max_length=100)
def get_absolute_url(self):
return reverse('help:kb_category', kwargs=dict(category=self.slug))
def get_top_entries(self, n=None):
n = n or config.KB_MAX_TOP_ENTRIES
return KbEntry.objects.get_top(n, category=self)
def get_entry_count(self):
return self.entry_set.filter(internal=False).count()
def __str__(self):
return self.name
@property
def name(self):
return get_internationalized(self.name_set, 'name')
@property
def description(self):
return get_internationalized(self.description_set, 'description')
class Meta:
verbose_name = "Knowledgebase Category"
verbose_name_plural = "Knowledgebase Categories"
class KbCategoryName(models.Model):
category = models.ForeignKey(KbCategory, on_delete=models.CASCADE,
related_name='name_set')
language = models.CharField(max_length=2)
name = models.CharField(max_length=100)
class KbCategoryDescription(models.Model):
category = models.ForeignKey(KbCategory, on_delete=models.CASCADE,
related_name='description_set')
language = models.CharField(max_length=2)
description = models.TextField()
class KbEntry(models.Model):
create_date = models.DateTimeField(auto_now_add=True, editable=False)
category = models.ForeignKey(KbCategory, on_delete=models.CASCADE,
related_name='entry_set')
title = models.CharField(max_length=50)
internal = models.BooleanField(default=False)
def vote(self, user, v):
vote = self.vote_set.filter(user=user).first()
if vote:
if vote.vote == v:
return
vote.vote = v
vote.save()
else:
v = KbEntryVote(entry=self, user=user, vote=v)
v.save()
def get_score(self):
return self.vote_set.aggregate(Sum('vote'))['vote__sum'] or 0
def get_vote_count(self):
return self.vote_set.count()
def get_absolute_url(self):
return reverse('help:kb_entry', kwargs=dict(category=self.category.slug, entry=self.id))
@property
def question(self):
return self.question_set.filter(language=get_language()).first().question
@property
def answer(self):
return self.answer_set.filter(language=get_language()).first().answer
def __str__(self):
return self.question
class Meta:
verbose_name = "Knowledgebase Entry"
verbose_name_plural = "Knowledgebase Entries"
class KbEntryManager(models.Manager):
def get_top(self, n, **kwargs):
return (self.filter(internal=False, **kwargs)
.annotate(score=Coalesce(Sum('vote_set__vote'), 0))
.order_by('-score', 'id')
[:n])
objects = KbEntryManager()
class KbEntryQuestion(models.Model):
entry = models.ForeignKey(KbEntry, on_delete=models.CASCADE,
related_name='question_set')
language = models.CharField(max_length=2)
question = models.CharField(max_length=200)
class KbEntryAnswer(models.Model):
entry = models.ForeignKey(KbEntry, on_delete=models.CASCADE,
related_name='answer_set')
language = models.CharField(max_length=2)
answer = HTMLField()
class KbEntryVote(models.Model):
entry = models.ForeignKey(KbEntry, on_delete=models.CASCADE,
related_name='vote_set')
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
null=True)
create_date = models.DateTimeField(auto_now_add=True, editable=False)
vote = models.IntegerField()
def __str__(self):
return 'Vote %+d on %s by %s' % (self.vote, self.entry, self.user)
class Meta:
verbose_name = "Knowledgebase Entry Vote"