mirror of
https://github.com/pretix/pretix.git
synced 2026-05-03 14:54:04 +00:00
Control UI for questions
This commit is contained in:
@@ -444,7 +444,7 @@ class Question(models.Model):
|
||||
verbose_name_plural = _("Questions")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return self.question
|
||||
|
||||
|
||||
class Item(models.Model):
|
||||
@@ -513,7 +513,7 @@ class Item(models.Model):
|
||||
)
|
||||
questions = models.ManyToManyField(
|
||||
Question,
|
||||
related_name='questions',
|
||||
related_name='items',
|
||||
verbose_name=_("Questions"),
|
||||
blank=True,
|
||||
help_text=_(
|
||||
|
||||
@@ -25,8 +25,9 @@
|
||||
{% bootstrap_field form.tax_rate layout="horizontal" %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{% trans "Variations" %}</legend>
|
||||
<legend>{% trans "Advanced settings" %}</legend>
|
||||
{% bootstrap_field form.properties layout="horizontal" %}
|
||||
{% bootstrap_field form.questions layout="horizontal" %}
|
||||
</fieldset>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<li {% if "event.items" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.items' organizer=request.event.organizer.slug event=request.event.slug %}">{% trans "Items" %}</a></li>
|
||||
<li {% if "event.items.categories" in url_name %}class="active"{% endif %}><a href="{% url 'control:event.items.categories' organizer=request.event.organizer.slug event=request.event.slug %}">{% trans "Categories" %}</a></li>
|
||||
<li {% if "event.items.properties" in url_name %}class="active"{% endif %}><a href="{% url 'control:event.items.properties' organizer=request.event.organizer.slug event=request.event.slug %}">{% trans "Properties" %}</a></li>
|
||||
<li {% if "event.items.questions" in url_name %}class="active"{% endif %}><a href="{% url 'control:event.items.questions' organizer=request.event.organizer.slug event=request.event.slug %}">{% trans "Questions" %}</a></li>
|
||||
</ul>
|
||||
{% block inside %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<tr>
|
||||
<th>{% trans "Item categories" %}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
28
src/tixlcontrol/templates/tixlcontrol/items/question.html
Normal file
28
src/tixlcontrol/templates/tixlcontrol/items/question.html
Normal file
@@ -0,0 +1,28 @@
|
||||
{% extends "tixlcontrol/items/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block title %}{% trans "Question" %}{% endblock %}
|
||||
{% block inside %}
|
||||
<h1>{% trans "Question" %}</h1>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% if "success" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "Your changes have been saved." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<fieldset>
|
||||
<legend>{% trans "General information" %}</legend>
|
||||
{% bootstrap_field form.question layout="horizontal" %}
|
||||
{% bootstrap_field form.type layout="horizontal" %}
|
||||
{% bootstrap_field form.required layout="horizontal" %}
|
||||
</fieldset>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,27 @@
|
||||
{% extends "tixlcontrol/items/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block title %}{% trans "Delete question" %}{% endblock %}
|
||||
{% block inside %}
|
||||
<h1>{% trans "Delete question" %}</h1>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<p>{% blocktrans %}Are you sure you want to the question <strong>{{ question }}</strong>?{% endblocktrans %}</p>
|
||||
{% if dependent|length > 0 %}
|
||||
<p>{% blocktrans %}All answers to the question given by the buyers of the following tickets will be <strong>permanently lost</strong>.{% endblocktrans %}</p>
|
||||
{% for item in dependent %}
|
||||
<li><a href="{% url "control:event.item" organizer=request.event.organizer.slug event=request.event.slug item=item.pk %}">{{ item.name }}</a></li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{% trans "Confirm" %}
|
||||
</button>
|
||||
<a href="{% url "control:event.items.properties" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default">
|
||||
{% trans "Cancel" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
40
src/tixlcontrol/templates/tixlcontrol/items/questions.html
Normal file
40
src/tixlcontrol/templates/tixlcontrol/items/questions.html
Normal file
@@ -0,0 +1,40 @@
|
||||
{% extends "tixlcontrol/items/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Questions" %}{% endblock %}
|
||||
{% block inside %}
|
||||
<h1>{% trans "Questions" %}</h1>
|
||||
{% if "updated" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "Your changes have been saved." %}
|
||||
</div>
|
||||
{% elif "created" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "A new question has been created." %}
|
||||
</div>
|
||||
{% elif "deleted" in request.GET %}
|
||||
<div class="alert alert-success">
|
||||
{% trans "The question has been deleted." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<p>
|
||||
<a href="{% url "control:event.items.questions.add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create new question" %}</a>
|
||||
</p>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Question" %}</th>
|
||||
<th>{% trans "Type" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for q in questions %}
|
||||
<tr>
|
||||
<td><strong><a href="{% url "control:event.items.questions.edit" organizer=request.event.organizer.slug event=request.event.slug question=q.pk %}">{{ q.question }}</a></strong></td>
|
||||
<td>{{ q.get_type_display }}</td>
|
||||
<td class="text-right"><a href="{% url "control:event.items.questions.delete" organizer=request.event.organizer.slug event=request.event.slug question=q.pk %}"" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
@@ -19,16 +19,20 @@ urlpatterns += patterns(
|
||||
'tixlcontrol.views',
|
||||
url(r'^$', 'event.index', name='event.index'),
|
||||
url(r'^settings$', event.EventUpdate.as_view(), name='event.settings'),
|
||||
url(r'^items$', item.ItemList.as_view(), name='event.items'),
|
||||
url(r'^items/$', item.ItemList.as_view(), name='event.items'),
|
||||
url(r'^items/(?P<item>\d+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
|
||||
url(r'^items/(?P<item>\d+)/variations$', item.ItemVariations.as_view(), name='event.item.variations'),
|
||||
url(r'^categories/$', item.CategoryList.as_view(), name='event.items.categories'),
|
||||
url(r'^category/(?P<category>\d+)/delete$', item.CategoryDelete.as_view(), name='event.items.categories.delete'),
|
||||
url(r'^category/(?P<category>\d+)/up$', item.category_move_up, name='event.items.categories.up'),
|
||||
url(r'^category/(?P<category>\d+)/down$', item.category_move_down, name='event.items.categories.down'),
|
||||
url(r'^category/(?P<category>\d+)/$', item.CategoryUpdate.as_view(), name='event.items.categories.edit'),
|
||||
url(r'^category/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'),
|
||||
url(r'^properties$', item.PropertyList.as_view(), name='event.items.properties'),
|
||||
url(r'^categories/(?P<category>\d+)/delete$', item.CategoryDelete.as_view(), name='event.items.categories.delete'),
|
||||
url(r'^categories/(?P<category>\d+)/up$', item.category_move_up, name='event.items.categories.up'),
|
||||
url(r'^categories/(?P<category>\d+)/down$', item.category_move_down, name='event.items.categories.down'),
|
||||
url(r'^categories/(?P<category>\d+)/$', item.CategoryUpdate.as_view(), name='event.items.categories.edit'),
|
||||
url(r'^categories/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'),
|
||||
url(r'^questions/$', item.QuestionList.as_view(), name='event.items.questions'),
|
||||
url(r'^questions/(?P<question>\d+)/delete$', item.QuestionDelete.as_view(), name='event.items.questions.delete'),
|
||||
url(r'^questions/(?P<question>\d+)/$', item.QuestionUpdate.as_view(), name='event.items.questions.edit'),
|
||||
url(r'^questions/add$', item.QuestionCreate.as_view(), name='event.items.questions.add'),
|
||||
url(r'^properties/$', item.PropertyList.as_view(), name='event.items.properties'),
|
||||
url(r'^properties/(?P<property>\d+)/$', item.PropertyUpdate.as_view(), name='event.items.properties.edit'),
|
||||
url(r'^properties/(?P<property>\d+)/delete$', item.PropertyDelete.as_view(), name='event.items.properties.delete'),
|
||||
url(r'^properties/add$', item.PropertyCreate.as_view(), name='event.items.properties.add'),
|
||||
|
||||
@@ -10,7 +10,7 @@ from django import forms
|
||||
from django.shortcuts import redirect
|
||||
from django.forms.models import inlineformset_factory
|
||||
|
||||
from tixlbase.models import Item, ItemCategory, Property, ItemVariation, PropertyValue
|
||||
from tixlbase.models import Item, ItemCategory, Property, ItemVariation, PropertyValue, Question
|
||||
from tixlcontrol.permissions import EventPermissionRequiredMixin, event_permission_required
|
||||
from tixlcontrol.views.forms import TolerantFormsetModelForm
|
||||
|
||||
@@ -315,12 +315,103 @@ class PropertyDelete(EventPermissionRequiredMixin, DeleteView):
|
||||
}) + '?deleted=true'
|
||||
|
||||
|
||||
class QuestionList(ListView):
|
||||
model = Question
|
||||
context_object_name = 'questions'
|
||||
template_name = 'tixlcontrol/items/questions.html'
|
||||
|
||||
def get_queryset(self):
|
||||
return self.request.event.questions.all()
|
||||
|
||||
|
||||
class QuestionForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Question
|
||||
localized_fields = '__all__'
|
||||
fields = [
|
||||
'question',
|
||||
'type',
|
||||
'required',
|
||||
]
|
||||
|
||||
|
||||
class QuestionDelete(EventPermissionRequiredMixin, DeleteView):
|
||||
model = Question
|
||||
template_name = 'tixlcontrol/items/question_delete.html'
|
||||
permission = 'can_change_items'
|
||||
context_object_name = 'question'
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
url = resolve(self.request.path_info)
|
||||
return self.request.event.questions.get(
|
||||
id=url.kwargs['question']
|
||||
)
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
context = super().get_context_data(*args, **kwargs)
|
||||
context['dependent'] = list(self.get_object().items.all())
|
||||
return context
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
self.object.items.update(category=None)
|
||||
success_url = self.get_success_url()
|
||||
self.object.delete()
|
||||
return HttpResponseRedirect(success_url)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('control:event.items.questions', kwargs={
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'event': self.request.event.slug,
|
||||
}) + '?deleted=true'
|
||||
|
||||
|
||||
class QuestionUpdate(EventPermissionRequiredMixin, UpdateView):
|
||||
model = Question
|
||||
form_class = QuestionForm
|
||||
template_name = 'tixlcontrol/items/question.html'
|
||||
permission = 'can_change_items'
|
||||
context_object_name = 'question'
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
url = resolve(self.request.path_info)
|
||||
return self.request.event.questions.get(
|
||||
id=url.kwargs['question']
|
||||
)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('control:event.items.questions', kwargs={
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'event': self.request.event.slug,
|
||||
}) + '?updated=true'
|
||||
|
||||
|
||||
class QuestionCreate(EventPermissionRequiredMixin, CreateView):
|
||||
model = Question
|
||||
form_class = QuestionForm
|
||||
template_name = 'tixlcontrol/items/question.html'
|
||||
permission = 'can_change_items'
|
||||
context_object_name = 'question'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('control:event.items.questions', kwargs={
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'event': self.request.event.slug,
|
||||
}) + '?created=true'
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.event = self.request.event
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class ItemUpdateFormGeneral(forms.ModelForm):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['category'].queryset = self.instance.event.categories.all()
|
||||
self.fields['properties'].queryset = self.instance.event.properties.all()
|
||||
self.fields['questions'].queryset = self.instance.event.questions.all()
|
||||
|
||||
class Meta:
|
||||
model = Item
|
||||
@@ -334,6 +425,7 @@ class ItemUpdateFormGeneral(forms.ModelForm):
|
||||
'default_price',
|
||||
'tax_rate',
|
||||
'properties',
|
||||
'questions',
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user