question as csv

This commit is contained in:
Holger Sielaff
2024-07-13 14:38:42 +02:00
parent e7b2dff233
commit 1531b0f6d3
6 changed files with 99 additions and 44 deletions

View File

@@ -1,5 +1,5 @@
import csv
import json
import logging
import os
from colorfield.fields import ColorField
@@ -12,6 +12,7 @@ from filer.fields.file import FilerFileField
from lib.core.db.models.base import SharedPermissionBase
from lib.core.db.models.mixins import DateAware, AuthorAware, DescriptionAware, NameAware, PublishedAware
from tablequizwiki.settings import BASE_DIR
class MediaFile(NameAware, DateAware, AuthorAware, DescriptionAware):
@@ -88,14 +89,12 @@ class Question(DateAware, AuthorAware, PublishedAware, DescriptionAware):
| models.Q(buzzword__icontains=term) \
| models.Q(labels__name__icontains=term)
@staticmethod
def get_by_tearchterm(term, queryset=None):
if not queryset:
queryset = Question.objects
return queryset.filter(Question.searchdomain(term)).annotate(cnt=models.Count('id'))
def to_view(self, for_players: bool = False):
ret = {}
ret['name'] = '{}{}'.format(self.name, f'({self.buzzword})' if self.buzzword else '')
@@ -111,15 +110,39 @@ def to_view(self, for_players: bool = False):
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
@property
def zippath(self):
return str(BASE_DIR) + f'/filestore/zip/question.{self.id}.zip'
@property
def pdfpath(self):
return str(BASE_DIR) + f'/filestore/pdf/question.{self.id}.pdf'
@property
def csvpath(self):
return str(BASE_DIR) + f'/filestore/csv/question.{self.id}.csv'
def default_json(o):
if isinstance(o, (MediaFile,)):
return str(o)
return json.dumps(model_to_dict(o))
def to_csv(self, fh=None):
if fh:
cf = fh
else:
cf = open(self.csvpath, 'w')
items = self.to_view()
keys = items.keys()
dw = csv.DictWriter(cf, fieldnames=list(keys))
dw.writeheader()
dw.writerow(items)
if not fh:
cf.close()
return cf if fh else self.csvpath
class QuestionVersion(DateAware, AuthorAware):
question = models.ForeignKey(Question, on_delete=models.SET_NULL, null=True)

View File

@@ -1,5 +1,6 @@
{% extends 'base.html' %}
{% block content %}
<h3>Questions</h3>
<form action="/questions" method="get" id="search_q_form">
<div id="question-search-field" class="row mb-5 mt-5">
<div class="col-12 p-0">
@@ -23,6 +24,7 @@
<div class="col-3">Question</div>
<div class="col-1">Files</div>
<div class="col-1">Labels</div>
<div class="col-1"><i class="fa fa-download"></i></div>
</div>
{% for q in items %}
<div class="row p-2">
@@ -36,6 +38,9 @@
{% if not forloop.last %},{% endif %}
{% endfor %}
</div>
<div class="col-1">
<a href="/questions/{{ q.id }}/csv" target="_blank">CSV</a>
</div>
</div>
{% endfor %}
{% endif %}

View File

@@ -3,5 +3,6 @@ from content.views import public
urlpatterns = [
path('questions/', public.search_question, name='search-questions'),
path('questions/<int:id>/csv/', public.as_csv, name='csv-question'),
path('', public.search_question, name='search-questions'),
]

View File

@@ -1,3 +1,4 @@
from django.http import HttpResponseNotFound, HttpResponse, HttpResponseBadRequest
from django.shortcuts import render
from content.models import Question
@@ -12,3 +13,14 @@ def search_question(request):
else:
items = published.all()[:10]
return render(request, 'questions.html', {'items': items})
def as_csv(request, **kwargs):
try:
q = Question.objects.get(id=kwargs['id'])
response = HttpResponse(content_type='text/csv')
return q.to_csv(fh=response)
except KeyError:
return HttpResponseBadRequest('No id given')
except Question.DoesNotExist:
return HttpResponseNotFound('Question not found')

View File

@@ -62,13 +62,18 @@ class Quiz(AuthorAware, DateAware, PublishedAware):
return self.pdfpath
def to_csv(self, fh=None):
with open(self.csvpath, 'w') as cf:
if fh:
cf = fh
else:
cf = open(self.csvpath, 'w')
items = self.to_view()['items']
keys = items[0].keys()
dw = csv.DictWriter(cf, fieldnames=list(keys))
dw.writeheader()
dw.writerows(items)
return self.csvpath
if not fh:
cf.close()
return cf if fh else self.csvpath
def to_zip(self, fh=None):
with zipfile.ZipFile(self.zippath, 'w') as zf:

View File

@@ -11,6 +11,7 @@
-moz-border-radius: 4px;
border-radius: 4px;
}
.input-group-unstyled .input-group-addon {
border-radius: 4px;
border: 0px;
@@ -26,12 +27,20 @@
<body>
<div class="container mt-2">
<header>
<div class="row">
<div class="col-5">
<h1>Tablequiz DB</h1>
<nav>
<a class="nav-item" href="/questions/">Questions</a>
<a class="nav-item" href="/quizes/">Quizes</a>
</div>
<div class="col-7" style="vertical-align: bottom">
<nav style="vertical-align: bottom; width: auto; justify-content: flex-end" class="navbar right">
<a class="nav-item p-3 btn btn-outline-dark mx-2" href="/questions/">Questions</a>
<a class="nav-item p-3 btn btn-outline-dark mx-2" href="/quizes/">Quizes</a>
</nav>
</div>
</div>
</header>
<hr class="my-3 mx-0 p-0" />
{% block content %}
{% endblock %}