Save the submitters to the motion

This commit is contained in:
Oskar Hahn 2013-01-26 15:25:54 +01:00
parent 1ae140c11e
commit 1f87749742
7 changed files with 104 additions and 75 deletions

View File

@ -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):

View File

@ -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)

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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,
)

View File

@ -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)

View File

@ -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):