Save the submitters to the motion
This commit is contained in:
parent
1ae140c11e
commit
1f87749742
@ -19,6 +19,9 @@ from .models import Motion
|
||||
|
||||
|
||||
class BaseMotionForm(forms.ModelForm, CssClassMixin):
|
||||
"""
|
||||
Form to automaticly save the version data for a motion.
|
||||
"""
|
||||
class Meta:
|
||||
model = Motion
|
||||
fields = ()
|
||||
@ -38,12 +41,20 @@ class BaseMotionForm(forms.ModelForm, CssClassMixin):
|
||||
widget=forms.Textarea(), required=False, label=_("Reason"))
|
||||
|
||||
|
||||
class MotionCreateForm(BaseMotionForm):
|
||||
pass
|
||||
class MotionSubmitterMixin(forms.ModelForm):
|
||||
submitter = MultiplePersonFormField(label=_("Submitter"))
|
||||
|
||||
|
||||
class MotionUpdateForm(BaseMotionForm):
|
||||
pass
|
||||
class MotionSupporterMixin(forms.ModelForm):
|
||||
supporter = MultiplePersonFormField(required=False, label=_("Supporters"))
|
||||
|
||||
|
||||
|
||||
|
||||
class MotionTrivialChangesMixin(object):
|
||||
trivial_change = forms.BooleanField(
|
||||
required=False, label=_("Trivial change"),
|
||||
help_text=_("Trivial changes don't create a new version."))
|
||||
|
||||
|
||||
class ConfigForm(forms.Form, CssClassMixin):
|
||||
|
@ -31,49 +31,21 @@ from openslides.projector.models import SlideMixin
|
||||
from openslides.agenda.models import Item
|
||||
|
||||
|
||||
RELATION = (
|
||||
(1, _('Submitter')),
|
||||
(2, _('Supporter')))
|
||||
|
||||
|
||||
class RelatedPersonsManager(models.Manager):
|
||||
"""
|
||||
Manager for MotionRelatedPersons.
|
||||
|
||||
Returns a custom manager with gives a specific queryset for one type of
|
||||
persons.
|
||||
"""
|
||||
def __init__(self, relation, *args, **kwargs):
|
||||
super(RelatedPersonsManager, self).__init__(*args, **kwargs)
|
||||
for key, value in RELATION:
|
||||
if key == relation:
|
||||
self.relation = key
|
||||
break
|
||||
else:
|
||||
raise ValueError('Unknown relation with id %d' % relation)
|
||||
|
||||
def get_query_set(self):
|
||||
return (super(RelatedPersonsManager, self).get_query_set()
|
||||
.filter(relation=self.relation))
|
||||
|
||||
|
||||
class MotionRelatedPersons(models.Model):
|
||||
"""
|
||||
Saves the all persons related to a motion.
|
||||
|
||||
relation = 1: submitter
|
||||
relation = 2: supporter
|
||||
|
||||
The custom manager submitter and supporter return a queryset with the
|
||||
specific persons.
|
||||
"""
|
||||
submitter = RelatedPersonsManager(relation=1)
|
||||
supporter = RelatedPersonsManager(relation=2)
|
||||
objects = models.Manager()
|
||||
|
||||
# TODO: Save submitter and supporter in the same table
|
||||
class MotionSubmitter(models.Model):
|
||||
person = PersonField()
|
||||
relation = models.IntegerField(default=1, choices=RELATION)
|
||||
motion = models.ForeignKey('Motion', related_name="persons")
|
||||
motion = models.ForeignKey('Motion', related_name="submitter")
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.person)
|
||||
|
||||
|
||||
class MotionSupporter(models.Model):
|
||||
person = PersonField()
|
||||
motion = models.ForeignKey('Motion', related_name="supporter")
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.person)
|
||||
|
||||
|
||||
class Motion(SlideMixin, models.Model):
|
||||
@ -198,20 +170,6 @@ class Motion(SlideMixin, models.Model):
|
||||
|
||||
reason = property(get_reason, set_reason)
|
||||
|
||||
@property
|
||||
def submitter(self):
|
||||
"""
|
||||
Return a queryset with all submitter of this motion.
|
||||
"""
|
||||
return MotionRelatedPersons.submitter.filter(motion=self)
|
||||
|
||||
@property
|
||||
def supporter(self):
|
||||
"""
|
||||
Returns a queryset with all supporter of this motion.
|
||||
"""
|
||||
return MotionRelatedPersons.supporter.filter(motion=self)
|
||||
|
||||
@property
|
||||
def new_version(self):
|
||||
"""
|
||||
@ -292,9 +250,15 @@ class MotionVersion(models.Model):
|
||||
note = models.TextField(null=True, blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s Version %s" % (self.motion, self.get_version_number())
|
||||
return "%s Version %s" % (self.motion, self.version_number)
|
||||
|
||||
def get_version_number(self):
|
||||
def get_absolute_url(self, link='detail'):
|
||||
if link == 'view' or link == 'detail':
|
||||
return reverse('motion_version_detail', args=[str(self.motion.id),
|
||||
str(self.version_number)])
|
||||
|
||||
@property
|
||||
def version_number(self):
|
||||
if self.pk is None:
|
||||
return 'new'
|
||||
return (MotionVersion.objects.filter(motion=self.motion)
|
||||
|
@ -4,9 +4,21 @@
|
||||
{% load i18n %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}{{ block.super }} – {% trans "Motion" %} "{{ version.title }}"{% endblock %}
|
||||
{% block title %}{{ block.super }} – {% trans "Motion" %} "{{ motion.title }}"{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>Titel: {{ object.title }} </p>
|
||||
<p>Text: {{ object.text }}</p>
|
||||
<p>Titel: {{ motion.title }} </p>
|
||||
<p>Text: {{ motion.text }}</p>
|
||||
<p>Reason: {{ motion.reason }}</p>
|
||||
<p>Submitter: {% for submitter in motion.submitter.all %}{{ submitter.person }} {% endfor %}</p>
|
||||
|
||||
<ol>
|
||||
{% for motion_version in motion.versions.all %}
|
||||
{% if motion_version.id == motion.version.id %}
|
||||
<li><strong><a href="{% model_url motion_version %}">{{ motion_version }}</a></strong></li>
|
||||
{% else %}
|
||||
<li><a href="{% model_url motion_version %}">{{ motion_version }}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ol>
|
||||
{% endblock %}
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
{% block content %}
|
||||
<h1>{% trans "Motions" %}</h1>
|
||||
<ul>
|
||||
<ol>
|
||||
{% for motion in motion_list %}
|
||||
<li>{{ motion }}</li>
|
||||
<li><a href="{% model_url motion %}">{{ motion }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</ol>
|
||||
{% endblock %}
|
||||
|
@ -17,6 +17,7 @@ from django.db import transaction
|
||||
from django.db.models import Model
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.http import Http404
|
||||
|
||||
from openslides.utils.pdf import stylesheet
|
||||
from openslides.utils.views import (
|
||||
@ -26,8 +27,10 @@ from openslides.utils.template import Tab
|
||||
from openslides.utils.utils import html_strong
|
||||
from openslides.projector.api import get_active_slide
|
||||
from openslides.projector.projector import Widget, SLIDE
|
||||
from .models import Motion
|
||||
from .forms import MotionCreateForm, MotionUpdateForm
|
||||
from openslides.config.models import config
|
||||
from .models import Motion, MotionSubmitter
|
||||
from .forms import (BaseMotionForm, MotionSubmitterMixin, MotionSupporterMixin,
|
||||
MotionTrivialChangesMixin)
|
||||
|
||||
|
||||
from django.views.generic.edit import ModelFormMixin
|
||||
@ -55,7 +58,10 @@ class MotionDetailView(DetailView):
|
||||
object = super(MotionDetailView, self).get_object()
|
||||
version_id = self.kwargs.get('version_id', None)
|
||||
if version_id is not None:
|
||||
try:
|
||||
object.version = int(version_id) -1
|
||||
except IndexError:
|
||||
raise Http404
|
||||
return object
|
||||
|
||||
motion_detail = MotionDetailView.as_view()
|
||||
@ -66,9 +72,28 @@ class MotionMixin(object):
|
||||
Mixin to add save the version-data to the motion-object
|
||||
"""
|
||||
def manipulate_object(self, form):
|
||||
super(MotionMixin, self).manipulate_object(form)
|
||||
for attr in ['title', 'text', 'reason']:
|
||||
setattr(self.object, attr, form.cleaned_data[attr])
|
||||
|
||||
def post_save(self, form):
|
||||
super(MotionMixin, self).post_save(form)
|
||||
# TODO: only delete and save neccessary submitters
|
||||
self.object.submitter.all().delete()
|
||||
MotionSubmitter.objects.bulk_create(
|
||||
[MotionSubmitter(motion=self.object, person=person)
|
||||
for person in form.cleaned_data['submitter']])
|
||||
|
||||
def get_form_class(self):
|
||||
form_classes = [BaseMotionForm]
|
||||
if config['motion_allow_trivial_change']:
|
||||
form_classes.append(MotionTrivialChangesMixin)
|
||||
if self.request.user.has_perm('motion.can_manage_motion'):
|
||||
form_classes.append(MotionSubmitterMixin)
|
||||
if config['motion_min_supporters'] > 0:
|
||||
form_classes.append(MotionSupporterMixin)
|
||||
return type('MotionForm', tuple(form_classes), {})
|
||||
|
||||
|
||||
class MotionCreateView(MotionMixin, CreateView):
|
||||
"""
|
||||
@ -76,7 +101,6 @@ class MotionCreateView(MotionMixin, CreateView):
|
||||
"""
|
||||
permission_required = 'motion.can_create_motion'
|
||||
model = Motion
|
||||
form_class = MotionCreateForm
|
||||
|
||||
motion_create = MotionCreateView.as_view()
|
||||
|
||||
@ -85,7 +109,21 @@ class MotionUpdateView(MotionMixin, UpdateView):
|
||||
"""
|
||||
Update a motion.
|
||||
"""
|
||||
# TODO: set permissions
|
||||
model = Motion
|
||||
form_class = MotionUpdateForm
|
||||
apply_url = ''
|
||||
|
||||
motion_edit = MotionUpdateView.as_view()
|
||||
|
||||
|
||||
def register_tab(request):
|
||||
"""
|
||||
Register the projector tab.
|
||||
"""
|
||||
selected = request.path.startswith('/motion/')
|
||||
return Tab(
|
||||
title=_('Motions'),
|
||||
url=reverse('motion_list'),
|
||||
permission=request.user.has_perm('motion.can_see_motion'),
|
||||
selected=selected,
|
||||
)
|
||||
|
@ -35,6 +35,7 @@ def active(request, pattern):
|
||||
|
||||
@register.simple_tag
|
||||
def model_url(object, link='view'):
|
||||
# TODO: Rename to object_url
|
||||
return object.get_absolute_url(link)
|
||||
|
||||
|
||||
|
@ -113,7 +113,7 @@ class SuccessUrlMixin(object):
|
||||
if 'apply' in self.request.POST:
|
||||
return reverse(self.get_apply_url(), args=[self.object.id])
|
||||
if self.success_url:
|
||||
url = reverse(success_url)
|
||||
url = reverse(self.success_url)
|
||||
else:
|
||||
try:
|
||||
url = self.object.get_absolute_url()
|
||||
@ -230,12 +230,15 @@ class ModelFormMixin(object):
|
||||
self.object = form.save(commit=False)
|
||||
self.manipulate_object(form)
|
||||
self.object.save()
|
||||
form.save_m2m()
|
||||
self.post_save(form)
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
|
||||
def manipulate_object(self, form):
|
||||
pass
|
||||
|
||||
def post_save(self, form):
|
||||
form.save_m2m()
|
||||
|
||||
|
||||
class UpdateView(PermissionMixin, SuccessUrlMixin, ExtraContextMixin,
|
||||
ModelFormMixin, _UpdateView):
|
||||
|
Loading…
Reference in New Issue
Block a user