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
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"
|
|
|