Files
Tablequizwiki/content/models.py
Holger Sielaff 030d3c8059 initial
2024-07-03 21:41:03 +02:00

151 lines
5.4 KiB
Python

import json
import logging
import os
from colorfield.fields import ColorField
from django.contrib.auth.models import User
from django.db import models
from django.dispatch import receiver
from django.forms.models import model_to_dict
from django.utils.safestring import mark_safe
from filer.fields.file import FilerFileField
from lib import get_current_user
class MediaFile(models.Model):
name = models.CharField(max_length=25, unique=True, db_index=True)
# https://django-filer.readthedocs.io/en/latest/extending_filer.html
# https://pypi.org/project/django-thumbnails/
file = FilerFileField(on_delete=models.RESTRICT, related_name='media_file')
description = models.TextField(null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, default=get_current_user)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
def __repr__(self):
return self.file.name
class Link(models.Model):
name = models.CharField(max_length=25, null=True, blank=True, db_index=True)
url = models.URLField(unique=True, db_index=True)
description = models.TextField(null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, default=get_current_user)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.url
def __repr__(self):
return self.url
class Level(models.Model):
name = models.CharField(max_length=25, unique=True, db_index=True)
value = models.IntegerField(unique=True, db_index=True)
description = models.TextField(null=True, blank=True)
color = ColorField(default='#F90F90')
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, default=get_current_user)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.value} - {self.name}'
def __repr__(self):
return f'{self.value}'
class Label(models.Model):
name = models.CharField(max_length=25, unique=True, db_index=True)
description = models.TextField(null=True, blank=True)
color = ColorField(default='#666666')
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, default=get_current_user)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
def __repr__(self):
return self.name
class Question(models.Model):
name = models.CharField(max_length=500, unique=True, db_index=True)
question = models.TextField(db_index=True)
buzzword = models.CharField(max_length=25, null=True, blank=True)
awnser = models.TextField(db_index=True)
level = models.ForeignKey(Level, on_delete=models.SET_NULL, null=True)
description = models.TextField(null=True, blank=True)
labels = models.ManyToManyField(Label, blank=True)
medias = models.ManyToManyField(MediaFile, blank=True)
links = models.ManyToManyField(Link, blank=True)
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
def __repr__(self):
return self.name
def to_view(self, for_players: bool = False):
ret = {}
ret['name'] = '{}{}'.format(self.name, f'({self.buzzword})' if self.buzzword else '')
ret['question'] = self.question
if self.description:
ret['question'] += ' \n\n------------------------------\n\n' + self.description
ret['awnser'] = self.awnser
ret['level'] = self.level.value
ret['medias'] = []
ret['links'] = []
for media in self.medias.all():
ret.setdefault('medias', []).append(os.path.basename(media.file.path))
for link in self.links.all():
ret.setdefault('links', []).append(link.url)
ret['question'] = mark_safe(ret['question'].replace('\n', '\n<br />'))
logging.error(ret)
return ret
def default_json(o):
if isinstance(o, (MediaFile,)):
return str(o)
return json.dumps(model_to_dict(o))
class QuestionVersion(models.Model):
question = models.ForeignKey(Question, on_delete=models.SET_NULL, null=True)
data = models.JSONField()
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f'{self.question} - {self.created_at}' if self.question else f'{self.data.name} - {self.created_at}'
@receiver(models.signals.post_save, sender=Question)
def versionize_question(sender, instance: Question, *args, **kwargs):
data = model_to_dict(instance)
# to be able to json.dumps in model
data['medias'] = [{'id': m.id, '__str__': str(m)} for m in data['medias']]
data['links'] = [{'id': m.id, '__str__': str(m)} for m in data['links']]
data['labels'] = [{'id': m.id, '__str__': str(m)} for m in data['labels']]
QuestionVersion.objects.create(
question=instance,
data=data,
# https://django-crum.readthedocs.io/en/latest/
# from crum import get_current_user
# author=get_current_user(),
)