.
This commit is contained in:
@@ -52,6 +52,9 @@ class AnatomyQuestionTable(tables.Table):
|
||||
# text='Clone',
|
||||
# args=[A('pk')],
|
||||
# orderable=False)
|
||||
delete = tables.LinkColumn(
|
||||
"anatomy:question_delete", text="Delete", args=[A("pk")], orderable=False
|
||||
)
|
||||
exams = tables.ManyToManyColumn(verbose_name="Exams")
|
||||
|
||||
class Meta:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{% include 'confirm_delete.html' %}
|
||||
@@ -23,6 +23,7 @@
|
||||
<div class="question">
|
||||
<a href="{% url 'anatomy:anatomy_question_update' question.id %}" title="Edit the Question">Edit</a>
|
||||
<a href="{% url 'anatomy:question_clone' question.id %}" title="Clone the Question">Clone</a>
|
||||
<a href="{% url 'anatomy:question_delete' pk=question.pk %}" title="Delete the Question">Delete</a>
|
||||
<a href="{% url 'admin:anatomy_anatomyquestion_change' question.id %}"
|
||||
title="Edit the Question using the admin interface">Admin Edit</a>
|
||||
<div class="date">
|
||||
|
||||
@@ -15,6 +15,7 @@ urlpatterns = [
|
||||
views.answer_question,
|
||||
name="answer_question"),
|
||||
path("question/<int:pk>/clone", views.QuestionClone.as_view(), name="question_clone"),
|
||||
path("question/<int:pk>/delete", views.QuestionDelete.as_view(), name="question_delete"),
|
||||
path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
path("exam/<int:pk>/mark", views.AnatomyExamViews.mark_overview, name="mark_overview"),
|
||||
path("exam/<int:pk>/<int:sk>/", views.exam_take, name="exam_take"),
|
||||
|
||||
+13
-1
@@ -6,6 +6,7 @@ from django import forms
|
||||
# from django.contrib.auth.models import User
|
||||
from django.contrib.auth.decorators import login_required, user_passes_test
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
||||
@@ -64,6 +65,14 @@ from django.template.defaulttags import register
|
||||
|
||||
from generic.mixins import SuperuserRequiredMixin
|
||||
|
||||
class AuthorOrCheckerRequiredMixin(object):
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super().get_object(*args, **kwargs)
|
||||
if self.request.user.groups.filter(name="anatomy_checker").exists():
|
||||
return obj
|
||||
if self.request.user not in obj.author.all():
|
||||
raise PermissionDenied() # or Http404
|
||||
return obj
|
||||
|
||||
@register.filter
|
||||
def get_item(dictionary, key):
|
||||
@@ -948,4 +957,7 @@ AnatomyExamViews = ExamViews(Exam, "anatomy", "anatomy", loadJsonAnswer)
|
||||
|
||||
class UserAnswerDelete(SuperuserRequiredMixin, DeleteView):
|
||||
model = CidUserAnswer
|
||||
success_url = reverse_lazy("anatomy:anatomy_user_answer_view")
|
||||
success_url = reverse_lazy("anatomy:anatomy_user_answer_view")
|
||||
class QuestionDelete(AuthorOrCheckerRequiredMixin, DeleteView):
|
||||
model = AnatomyQuestion
|
||||
success_url = reverse_lazy("anatomy:anatomy_question_view")
|
||||
@@ -57,6 +57,9 @@ class LongTable(tables.Table):
|
||||
clone = tables.LinkColumn(
|
||||
"longs:long_clone", text="Clone", args=[A("pk")], orderable=False
|
||||
)
|
||||
delete = tables.LinkColumn(
|
||||
"longs:long_delete", text="Delete", args=[A("pk")], orderable=False
|
||||
)
|
||||
series = LongImageColumn("Images", orderable=False)
|
||||
|
||||
#series = tables.ManyToManyColumn(verbose_name="Exams")
|
||||
@@ -93,6 +96,10 @@ class LongSeriesTable(tables.Table):
|
||||
|
||||
images = LongSeriesImageColumn("Images", orderable=False)
|
||||
|
||||
delete = tables.LinkColumn(
|
||||
"longs:long_series_delete", text="Delete", args=[A("pk")], orderable=False
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = LongSeries
|
||||
template_name = "django_tables2/bootstrap4.html"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{% include 'confirm_delete.html' %}
|
||||
@@ -0,0 +1 @@
|
||||
{% include 'confirm_delete.html' %}
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
<a href="{% url 'longs:long_update' pk=question.pk %}" title="Edit the Long">Edit</a>
|
||||
<a href="{% url 'longs:long_clone' pk=question.pk %}" title="Clone the Long (duplicate everything but the images)">Clone</a>
|
||||
<a href="{% url 'longs:long_delete' pk=question.pk %}" title="Delete the Rapid">Delete</a>
|
||||
<a href="{% url 'longs:long_add_note' pk=question.pk %}"> Add Note</a>
|
||||
{% if request.user.is_superuser %}
|
||||
<a href="{% url 'admin:longs_long_change' question.id %}" title="Edit the Long using the admin interface">Admin Edit</a>
|
||||
|
||||
@@ -11,6 +11,7 @@ urlpatterns = [
|
||||
path("question/", views.LongView.as_view(), name="long_view"),
|
||||
path("series/", views.LongSeriesView.as_view(), name="long_series_view"),
|
||||
path("series/<int:pk>", views.long_series_detail, name="long_series_detail"),
|
||||
path("series/<int:pk>/delete", views.LongSeriesDelete.as_view(), name="long_series_delete"),
|
||||
# path("unchecked/", views.unchecked_list, name="unchecked_list"),
|
||||
# path("verified/<int:pk>/", views.verified_detail, name="verified_detail"),
|
||||
path("question/<int:pk>/", views.long_detail, name="long_detail"),
|
||||
@@ -19,6 +20,7 @@ urlpatterns = [
|
||||
# path("verified/", views.verified, name="verified"),
|
||||
# path("all_questions/", views.all_questions, name="all_questions"),
|
||||
path("question/<int:pk>/scrap", views.long_scrap, name="long_scrap"),
|
||||
path("question/<int:pk>/delete", views.LongDelete.as_view(), name="long_delete"),
|
||||
path("exam/<int:pk>/<int:sk>/<int:tk>/mark", views.mark_answer, name="mark_answer"),
|
||||
path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
path("exam/<int:pk>/mark", views.LongExamViews.mark_overview, name="mark_overview"),
|
||||
|
||||
+13
-2
@@ -63,7 +63,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class AuthorOrCheckerRequiredMixin(object):
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(UpdateView, self).get_object(*args, **kwargs)
|
||||
obj = super().get_object(*args, **kwargs)
|
||||
if self.request.user.groups.filter(name="long_checker").exists() or self.request.user.is_superuser:
|
||||
return obj
|
||||
if self.request.user not in obj.get_author_objects():
|
||||
@@ -71,7 +71,6 @@ class AuthorOrCheckerRequiredMixin(object):
|
||||
return obj
|
||||
|
||||
|
||||
|
||||
# def index(request):
|
||||
# other_longs = Long.objects.exclude(author=request.user.pk)
|
||||
# user_longs = Long.objects.filter(author=request.user.pk)
|
||||
@@ -228,6 +227,18 @@ class AddNote(LoginRequiredMixin, CreateView):
|
||||
|
||||
# form.instance.author.add(self.request.user.id)
|
||||
|
||||
#@login_required
|
||||
#@user_is_author_or_long_checker
|
||||
#def long_delete(request, pk):
|
||||
#q = get_object_or_404(Long, pk=pk)
|
||||
#q.delete()
|
||||
class LongDelete(AuthorOrCheckerRequiredMixin, DeleteView):
|
||||
model = Long
|
||||
success_url = reverse_lazy("longs:long_view")
|
||||
|
||||
class LongSeriesDelete(AuthorOrCheckerRequiredMixin, DeleteView):
|
||||
model = LongSeries
|
||||
success_url = reverse_lazy("longs:long_series_view")
|
||||
|
||||
@login_required
|
||||
def long_clone(request, pk):
|
||||
|
||||
@@ -38,6 +38,10 @@ class RapidTable(tables.Table):
|
||||
text='Clone',
|
||||
args=[A('pk')],
|
||||
orderable=False)
|
||||
delete = tables.LinkColumn('rapids:question_delete',
|
||||
text='Delete',
|
||||
args=[A('pk')],
|
||||
orderable=False)
|
||||
images = ImageColumn("images", orderable=False)
|
||||
|
||||
class Meta:
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
<a href="{% url 'rapids:rapid_update' pk=question.pk %}" title="Edit the Rapid">Edit</a>
|
||||
<a href="{% url 'rapids:rapid_clone' pk=question.pk %}" title="Clone the Rapid (duplicate everything but the images)">Clone</a>
|
||||
<a href="{% url 'rapids:question_delete' pk=question.pk %}" title="Delete the Rapid">Delete</a>
|
||||
<a href="{% url 'rapids:rapid_add_note' pk=question.pk %}"> Add Note</a>
|
||||
{% if request.user.is_superuser %}
|
||||
<a href="{% url 'admin:rapids_rapid_change' question.id %}" title="Edit the Rapid using the admin interface">Admin Edit</a>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{% include 'confirm_delete.html' %}
|
||||
@@ -17,6 +17,7 @@ urlpatterns = [
|
||||
#path("verified/", views.verified, name="verified"),
|
||||
#path("all_questions/", views.all_questions, name="all_questions"),
|
||||
path("question/<int:pk>/scrap", views.rapid_scrap, name="rapid_scrap"),
|
||||
path("question/<int:pk>/delete", views.QuestionDelete.as_view(), name="question_delete"),
|
||||
path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
path("exam/<int:pk>/mark", views.RapidExamViews.mark_overview, name="mark_overview"),
|
||||
# path("exam/<int:pk>/<int:sk>/", views.exam_take, name="exam_take"),
|
||||
|
||||
+4
-1
@@ -70,7 +70,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class AuthorOrCheckerRequiredMixin(object):
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super(UpdateView, self).get_object(*args, **kwargs)
|
||||
obj = super().get_object(*args, **kwargs)
|
||||
if self.request.user.groups.filter(name="rapid_checker").exists():
|
||||
return obj
|
||||
if self.request.user not in obj.author.all():
|
||||
@@ -871,5 +871,8 @@ def exam_scores_cid_user(request, pk, sk):
|
||||
)
|
||||
|
||||
|
||||
class QuestionDelete(AuthorOrCheckerRequiredMixin, DeleteView):
|
||||
model = Rapid
|
||||
success_url = reverse_lazy("rapids:rapid_view")
|
||||
|
||||
RapidExamViews = ExamViews(Exam, "rapids", "rapid", loadJsonAnswer)
|
||||
@@ -0,0 +1,13 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2>Deleting stuff</h2>
|
||||
|
||||
<form method="post">{% csrf_token %}
|
||||
<p>Are you sure you want to delete "{{ object }}"?</p>
|
||||
<input type="submit" value="Confirm">
|
||||
</form>
|
||||
|
||||
{% endblock content %}
|
||||
Reference in New Issue
Block a user