This commit is contained in:
Holger Sielaff
2024-09-10 12:32:53 +02:00
parent 1531b0f6d3
commit be447f4862
9 changed files with 179 additions and 7 deletions

View File

@@ -1,11 +1,32 @@
from django.contrib import admin
from django.utils.safestring import mark_safe
from content.models import Link, MediaFile, Question, QuestionVersion, Level, Label, SharedQuestion
from content.models import Link, MediaFile, Question, QuestionVersion, Level, Label, SharedQuestion, SubmittedQuestion
from lib.mixins import PermissionsAdminMixin
from lib.utils import color_label
class ActiveFilter(admin.SimpleListFilter):
title = "Aktiv/Inaktiv"
parameter_name = 'released'
def lookups(self, request, model_admin):
return [
(1, 'Inaktiv'),
(0, 'Aktiv')
]
def queryset(self, request, queryset):
v = int(self.value() or -1)
if v == 1:
return queryset.filter(**{self.parameter_name: True})
elif v == 0:
return queryset.filter(**{self.parameter_name: False})
else:
return queryset.filter(**{self.parameter_name: False})
# return queryset
@admin.register(SharedQuestion)
class SharedQuestionAdmin(admin.ModelAdmin):
search_fields = ('user__username',)
@@ -25,6 +46,11 @@ class LabelAdmin(PermissionsAdminMixin, admin.ModelAdmin):
list_editable = ('color',)
@admin.register(SubmittedQuestion)
class SubmittedQuestionAdmin(admin.ModelAdmin):
list_filter = [ActiveFilter,]
@admin.register(Question)
class QuestionAdmin(PermissionsAdminMixin, admin.ModelAdmin):
autocomplete_fields = ('medias', 'links', 'labels', 'shares')

View File

@@ -1,11 +1,11 @@
import csv
from datetime import datetime
import json
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
@@ -63,10 +63,55 @@ class SharedQuestion(SharedPermissionBase):
abstract = False
class SubmittedQuestion(DateAware):
name = models.CharField(max_length=500, unique=True)
buzzword = models.CharField(max_length=25, null=True, blank=True)
question = models.TextField()
awnser = models.TextField()
level = models.ForeignKey(Level, on_delete=models.SET_NULL, null=True, blank=True)
labels = models.ManyToManyField(Label, blank=True)
medias = models.ManyToManyField(MediaFile, blank=True)
links = models.ManyToManyField(Link, blank=True)
shares = models.ManyToManyField(SharedQuestion, blank=True)
release = models.BooleanField(default=False)
released = models.BooleanField(default=False)
released_at = models.DateTimeField(null=True,blank=True)
def __str__(self):
return f"{self.name} (#{self.id})"
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=SubmittedQuestion)
def release_submitted(sender, instance: SubmittedQuestion, **kwargs):
if instance.release:
n = Question.objects.create(
name=instance.name,
buzzword=instance.buzzword,
question=instance.question,
awnser=instance.awnser,
)
try:
n.labels.set(instance.labels.all())
n.level_id = instance.level_id
n.save()
except:
n.delete()
raise
instance.released = True
instance.release = False
instance.released_at = datetime.now()
instance.save()
class Question(DateAware, AuthorAware, PublishedAware, DescriptionAware):
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)
question = models.TextField(db_index=True)
awnser = models.TextField(db_index=True)
level = models.ForeignKey(Level, on_delete=models.SET_NULL, null=True)
labels = models.ManyToManyField(Label, blank=True)

View File

@@ -12,6 +12,7 @@
<i class="fa fa-search" onclick="document.getElementById('search_q_form').submit();"></i>
</span>
</div>
{# {{ form.captcha }} #}
</div>
</div>
</div>

View File

@@ -0,0 +1,50 @@
{% extends 'base.html' %}
{% block content %}
<style type="text/css" rel="stylesheet">
.form_wrapper label,
.form_wrapper legend {
display: block;
/*
float: left;
width: 25%;
*/
font-size: initial;
margin-bottom: 1em;
}
.form_wrapper textarea,
.form_wrapper input {
display: block;
/*
float: left;
width: 74%;
*/
margin-bottom: 1em;
width: 100%;
}
.form_wrapper fieldset input {
display: initial;
float: initial;
width: initial;
}
.form_wrapper fieldset {
width: 100%;
}
</style>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<div class="form_wrapper">
<form method="post" action="?">
{% csrf_token %}
{{ form.as_div }}
<input type="submit" value="Submit" />
</form>
</div>
{% endblock %}

View File

@@ -2,6 +2,7 @@ from django.urls.conf import path
from content.views import public
urlpatterns = [
path('add-question/', public.submit_question, name='add-questions'),
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,18 +1,64 @@
from django import forms
from django.http import HttpResponseNotFound, HttpResponse, HttpResponseBadRequest
from django.shortcuts import render
from django.shortcuts import render, redirect
from simplemathcaptcha.fields import MathCaptchaField
from content.models import Question
from content.models import Question, SubmittedQuestion
class SearchForm(forms.Form):
term = forms.CharField(max_length=100)
# captcha = MathCaptchaField()
class SubmitQuestion(forms.Form):
name = forms.CharField(max_length=500, required=True)
buzzword = forms.CharField(max_length=150, required=False)
question = forms.CharField(max_length=100000, widget=forms.Textarea, required=True)
awnser = forms.CharField(max_length=100000, widget=forms.Textarea, required=True)
captcha = MathCaptchaField()
# level = forms.ForeignKey(Level, on_delete=models.SET_NULL, null=True)
# labels = forms.ManyToManyField(Label, blank=True)
# medias = forms.ManyToManyField(MediaFile, blank=True)
# links = forms.ManyToManyField(Link, blank=True)
# shares = forms.ManyToManyField(SharedQuestion, blank=True)
def search_question(request):
term = request.GET.get('term')
items = []
published = Question.objects.filter(is_published=True)
form = SearchForm(data=request.GET)
if term:
items = Question.get_by_tearchterm(term, published)
if form.is_valid():
items = Question.get_by_tearchterm(term, published)
form.term = term
else:
return redirect('/')
else:
items = published.all()[:10]
return render(request, 'questions.html', {'items': items})
return render(request, 'questions.html', {'form': SearchForm(), 'items': items})
from django.contrib import messages
def submit_question(request):
if request.method == 'POST':
form = SubmitQuestion(data=request.POST)
if form.is_valid():
subq = SubmittedQuestion.objects.create(
name=form.cleaned_data['name'],
buzzword=form.cleaned_data['buzzword'],
question=form.cleaned_data['question'],
awnser=form.cleaned_data['awnser'],
)
messages.info(request, f"Angelegt mit ID {subq.id}")
return render(request, 'submit-question.html', {'form': SubmitQuestion()})
else:
[messages.error(request,f'Error in {err}') for err in form.errors]
return render(request, 'submit-question.html', {'form': form})
else:
form = SubmitQuestion()
return render(request, 'submit-question.html', {'form': form})
def as_csv(request, **kwargs):

View File

@@ -15,4 +15,5 @@ django-jazzmin
requests
django-rest-swagger
drf-yasg
django-simple-math-captcha
django-guardian

View File

@@ -41,6 +41,7 @@ INSTALLED_APPS = [
'colorfield',
'filer',
'rest_framework_swagger',
'simplemathcaptcha',
# 'guardian',
'api',
'content',

View File

@@ -35,6 +35,7 @@
<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>
<a class="nav-item p-3 btn btn-outline-success mx-2" href="/add-question/">Submit a Question</a>
</nav>
</div>