Merge pull request #1172 from ostcar/get_absolut_url_mixin
Added AbsoluteUrlMixin and used it in any model.
This commit is contained in:
commit
03c59303d7
@ -17,10 +17,11 @@ from openslides.projector.api import (get_active_slide, reset_countdown,
|
||||
update_projector, update_projector_overlay)
|
||||
from openslides.projector.models import SlideMixin
|
||||
from openslides.utils.exceptions import OpenSlidesError
|
||||
from openslides.utils.models import AbsoluteUrlMixin
|
||||
from openslides.utils.person.models import PersonField
|
||||
|
||||
|
||||
class Item(SlideMixin, MPTTModel):
|
||||
class Item(SlideMixin, AbsoluteUrlMixin, MPTTModel):
|
||||
"""
|
||||
An Agenda Item
|
||||
|
||||
@ -296,7 +297,7 @@ class SpeakerManager(models.Manager):
|
||||
return self.create(item=item, person=person, weight=weight + 1)
|
||||
|
||||
|
||||
class Speaker(models.Model):
|
||||
class Speaker(AbsoluteUrlMixin, models.Model):
|
||||
"""
|
||||
Model for the Speaker list.
|
||||
"""
|
||||
@ -346,10 +347,13 @@ class Speaker(models.Model):
|
||||
|
||||
def get_absolute_url(self, link='detail'):
|
||||
if link == 'detail':
|
||||
return self.person.get_absolute_url('detail')
|
||||
if link == 'delete':
|
||||
return reverse('agenda_speaker_delete',
|
||||
args=[self.item.pk, self.pk])
|
||||
url = self.person.get_absolute_url('detail')
|
||||
elif link == 'delete':
|
||||
url = reverse('agenda_speaker_delete',
|
||||
args=[self.item.pk, self.pk])
|
||||
else:
|
||||
url = super(Speaker, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
def check_and_update_projector(self):
|
||||
"""
|
||||
|
@ -11,6 +11,7 @@ from openslides.poll.models import (BaseOption, BasePoll, BaseVote,
|
||||
CollectInvalid, CollectVotesCast,
|
||||
PublishPollMixin)
|
||||
from openslides.projector.models import RelatedModelMixin, SlideMixin
|
||||
from openslides.utils.models import AbsoluteUrlMixin
|
||||
from openslides.utils.person import PersonField
|
||||
from openslides.utils.utils import html_strong
|
||||
|
||||
@ -37,7 +38,7 @@ class AssignmentCandidate(RelatedModelMixin, models.Model):
|
||||
return self.assignment
|
||||
|
||||
|
||||
class Assignment(SlideMixin, models.Model):
|
||||
class Assignment(SlideMixin, AbsoluteUrlMixin, models.Model):
|
||||
slide_callback_name = 'assignment'
|
||||
|
||||
STATUS = (
|
||||
@ -68,13 +69,15 @@ class Assignment(SlideMixin, models.Model):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self, link='detail'):
|
||||
if link == 'detail' or link == 'view':
|
||||
return reverse('assignment_detail', args=[str(self.id)])
|
||||
if link == 'update' or link == 'update':
|
||||
return reverse('assignment_update', args=[str(self.id)])
|
||||
if link == 'delete':
|
||||
return reverse('assignment_delete', args=[str(self.id)])
|
||||
return super(Assignment, self).get_absolute_url(link)
|
||||
if link == 'detail':
|
||||
url = reverse('assignment_detail', args=[str(self.pk)])
|
||||
elif link == 'update':
|
||||
url = reverse('assignment_update', args=[str(self.pk)])
|
||||
elif link == 'delete':
|
||||
url = reverse('assignment_delete', args=[str(self.pk)])
|
||||
else:
|
||||
url = super(Assignment, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
def get_slide_context(self, **context):
|
||||
context.update({
|
||||
@ -250,7 +253,7 @@ class AssignmentOption(BaseOption):
|
||||
|
||||
|
||||
class AssignmentPoll(RelatedModelMixin, CollectInvalid, CollectVotesCast,
|
||||
PublishPollMixin, BasePoll):
|
||||
PublishPollMixin, AbsoluteUrlMixin, BasePoll):
|
||||
option_class = AssignmentOption
|
||||
|
||||
assignment = models.ForeignKey(Assignment, related_name='poll_set')
|
||||
@ -259,12 +262,14 @@ class AssignmentPoll(RelatedModelMixin, CollectInvalid, CollectVotesCast,
|
||||
def __unicode__(self):
|
||||
return _("Ballot %d") % self.get_ballot()
|
||||
|
||||
@models.permalink
|
||||
def get_absolute_url(self, link='detail'):
|
||||
if link == 'view' or link == 'detail' or link == 'update':
|
||||
return ('assignment_poll_view', [str(self.pk)])
|
||||
if link == 'delete':
|
||||
return ('assignment_poll_delete', [str(self.pk)])
|
||||
def get_absolute_url(self, link='update'):
|
||||
if link == 'update':
|
||||
url = reverse('assignment_poll_view', args=[str(self.pk)])
|
||||
elif link == 'delete':
|
||||
url = reverse('assignment_poll_delete', args=[str(self.pk)])
|
||||
else:
|
||||
url = super(AssignmentPoll, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
def get_assignment(self):
|
||||
return self.assignment
|
||||
|
@ -1,7 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import warnings
|
||||
|
||||
from django import template
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
@ -26,16 +24,6 @@ def trans(value):
|
||||
return _(value)
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def model_url(object, link='view'):
|
||||
warnings.warn("model_url is deprecated; use absolute_url instead",
|
||||
DeprecationWarning)
|
||||
try:
|
||||
return object.get_absolute_url(link)
|
||||
except ValueError:
|
||||
return ''
|
||||
|
||||
|
||||
@register.filter
|
||||
def absolute_url(model, link=None):
|
||||
"""
|
||||
|
@ -8,10 +8,11 @@ from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.projector.models import SlideMixin
|
||||
from openslides.utils.models import AbsoluteUrlMixin
|
||||
from openslides.utils.person.models import PersonField
|
||||
|
||||
|
||||
class Mediafile(SlideMixin, models.Model):
|
||||
class Mediafile(SlideMixin, AbsoluteUrlMixin, models.Model):
|
||||
"""
|
||||
Class for uploaded files which can be delivered under a certain url.
|
||||
"""
|
||||
@ -74,10 +75,12 @@ class Mediafile(SlideMixin, models.Model):
|
||||
'update' or 'delete'.
|
||||
"""
|
||||
if link == 'update':
|
||||
return reverse('mediafile_update', kwargs={'pk': str(self.id)})
|
||||
if link == 'delete':
|
||||
return reverse('mediafile_delete', kwargs={'pk': str(self.id)})
|
||||
return super(Mediafile, self).get_absolute_url(link)
|
||||
url = reverse('mediafile_update', kwargs={'pk': str(self.pk)})
|
||||
elif link == 'delete':
|
||||
url = reverse('mediafile_delete', kwargs={'pk': str(self.pk)})
|
||||
else:
|
||||
url = super(Mediafile, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
def get_filesize(self):
|
||||
"""
|
||||
|
@ -13,12 +13,13 @@ from openslides.poll.models import (BaseOption, BasePoll, BaseVote,
|
||||
CollectInvalid, CollectVotesCast)
|
||||
from openslides.projector.models import RelatedModelMixin, SlideMixin
|
||||
from jsonfield import JSONField
|
||||
from openslides.utils.models import AbsoluteUrlMixin
|
||||
from openslides.utils.person import PersonField
|
||||
|
||||
from .exceptions import WorkflowError
|
||||
|
||||
|
||||
class Motion(SlideMixin, models.Model):
|
||||
class Motion(SlideMixin, AbsoluteUrlMixin, models.Model):
|
||||
"""
|
||||
The Motion Class.
|
||||
|
||||
@ -174,12 +175,14 @@ class Motion(SlideMixin, models.Model):
|
||||
The keyword argument 'link' can be 'detail', 'update' or 'delete'.
|
||||
"""
|
||||
if link == 'detail':
|
||||
return reverse('motion_detail', args=[str(self.id)])
|
||||
if link == 'update':
|
||||
return reverse('motion_update', args=[str(self.id)])
|
||||
if link == 'delete':
|
||||
return reverse('motion_delete', args=[str(self.id)])
|
||||
return super(Motion, self).get_absolute_url(link)
|
||||
url = reverse('motion_detail', args=[str(self.pk)])
|
||||
elif link == 'update':
|
||||
url = reverse('motion_update', args=[str(self.pk)])
|
||||
elif link == 'delete':
|
||||
url = reverse('motion_delete', args=[str(self.pk)])
|
||||
else:
|
||||
url = super(Motion, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
def version_data_changed(self, version):
|
||||
"""
|
||||
@ -515,7 +518,7 @@ class Motion(SlideMixin, models.Model):
|
||||
MotionLog.objects.create(motion=self, message_list=message_list, person=person)
|
||||
|
||||
|
||||
class MotionVersion(models.Model):
|
||||
class MotionVersion(AbsoluteUrlMixin, models.Model):
|
||||
"""
|
||||
A MotionVersion object saves some date of the motion.
|
||||
"""
|
||||
@ -558,12 +561,15 @@ class MotionVersion(models.Model):
|
||||
|
||||
The keyargument link can be 'detail' or 'delete'.
|
||||
"""
|
||||
if link == 'view' or link == 'detail':
|
||||
return reverse('motion_version_detail', args=[str(self.motion.id),
|
||||
str(self.version_number)])
|
||||
if link == 'delete':
|
||||
return reverse('motion_version_delete', args=[str(self.motion.id),
|
||||
str(self.version_number)])
|
||||
if link == 'detail':
|
||||
url = reverse('motion_version_detail', args=[str(self.motion.pk),
|
||||
str(self.version_number)])
|
||||
elif link == 'delete':
|
||||
url = reverse('motion_version_delete', args=[str(self.motion.pk),
|
||||
str(self.version_number)])
|
||||
else:
|
||||
url = super(MotionVersion, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
@property
|
||||
def active(self):
|
||||
@ -602,7 +608,7 @@ class MotionSupporter(models.Model):
|
||||
return unicode(self.person)
|
||||
|
||||
|
||||
class Category(models.Model):
|
||||
class Category(AbsoluteUrlMixin, models.Model):
|
||||
name = models.CharField(max_length=255, verbose_name=ugettext_lazy("Category name"))
|
||||
"""Name of the category."""
|
||||
|
||||
@ -617,9 +623,12 @@ class Category(models.Model):
|
||||
|
||||
def get_absolute_url(self, link='update'):
|
||||
if link == 'update':
|
||||
return reverse('motion_category_update', args=[str(self.id)])
|
||||
if link == 'delete':
|
||||
return reverse('motion_category_delete', args=[str(self.id)])
|
||||
url = reverse('motion_category_update', args=[str(self.pk)])
|
||||
elif link == 'delete':
|
||||
url = reverse('motion_category_delete', args=[str(self.pk)])
|
||||
else:
|
||||
url = super(Category, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
class Meta:
|
||||
ordering = ['prefix']
|
||||
@ -685,7 +694,8 @@ class MotionOption(BaseOption):
|
||||
"""The VoteClass, to witch this Class links."""
|
||||
|
||||
|
||||
class MotionPoll(RelatedModelMixin, CollectInvalid, CollectVotesCast, BasePoll):
|
||||
class MotionPoll(RelatedModelMixin, CollectInvalid, CollectVotesCast,
|
||||
AbsoluteUrlMixin, BasePoll):
|
||||
"""The Class to saves the poll results for a motion poll."""
|
||||
|
||||
motion = models.ForeignKey(Motion, related_name='polls')
|
||||
@ -718,11 +728,14 @@ class MotionPoll(RelatedModelMixin, CollectInvalid, CollectVotesCast, BasePoll):
|
||||
The keyargument 'link' can be 'update' or 'delete'.
|
||||
"""
|
||||
if link == 'update':
|
||||
return reverse('motion_poll_update', args=[str(self.motion.pk),
|
||||
str(self.poll_number)])
|
||||
if link == 'delete':
|
||||
return reverse('motion_poll_delete', args=[str(self.motion.pk),
|
||||
str(self.poll_number)])
|
||||
url = reverse('motion_poll_update', args=[str(self.motion.pk),
|
||||
str(self.poll_number)])
|
||||
elif link == 'delete':
|
||||
url = reverse('motion_poll_delete', args=[str(self.motion.pk),
|
||||
str(self.poll_number)])
|
||||
else:
|
||||
url = super(MotionPoll, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
def set_options(self):
|
||||
"""Create the option class for this poll."""
|
||||
|
@ -12,11 +12,12 @@ from django.utils.translation import ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.config.api import config
|
||||
from openslides.projector.models import SlideMixin
|
||||
from openslides.utils.models import AbsoluteUrlMixin
|
||||
from openslides.utils.person import Person, PersonMixin
|
||||
from openslides.utils.person.signals import receive_persons
|
||||
|
||||
|
||||
class User(SlideMixin, PersonMixin, Person, DjangoUser):
|
||||
class User(SlideMixin, PersonMixin, Person, AbsoluteUrlMixin, DjangoUser):
|
||||
slide_callback_name = 'user'
|
||||
person_prefix = 'user'
|
||||
|
||||
@ -65,12 +66,14 @@ class User(SlideMixin, PersonMixin, Person, DjangoUser):
|
||||
Return the URL to the user.
|
||||
"""
|
||||
if link == 'detail':
|
||||
return reverse('user_view', args=[str(self.id)])
|
||||
if link == 'update':
|
||||
return reverse('user_edit', args=[str(self.id)])
|
||||
if link == 'delete':
|
||||
return reverse('user_delete', args=[str(self.id)])
|
||||
return super(User, self).get_absolute_url(link)
|
||||
url = reverse('user_view', args=[str(self.pk)])
|
||||
elif link == 'update':
|
||||
url = reverse('user_edit', args=[str(self.pk)])
|
||||
elif link == 'delete':
|
||||
url = reverse('user_delete', args=[str(self.pk)])
|
||||
else:
|
||||
url = super(User, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
def get_slide_context(self, **context):
|
||||
# Does not call super. In this case the context would override the name
|
||||
@ -109,7 +112,7 @@ class User(SlideMixin, PersonMixin, Person, DjangoUser):
|
||||
return self.last_name.lower()
|
||||
|
||||
|
||||
class Group(SlideMixin, PersonMixin, Person, DjangoGroup):
|
||||
class Group(SlideMixin, PersonMixin, Person, AbsoluteUrlMixin, DjangoGroup):
|
||||
slide_callback_name = 'group'
|
||||
person_prefix = 'group'
|
||||
|
||||
@ -130,12 +133,14 @@ class Group(SlideMixin, PersonMixin, Person, DjangoGroup):
|
||||
Return the URL to the user group.
|
||||
"""
|
||||
if link == 'detail':
|
||||
return reverse('user_group_view', args=[str(self.pk)])
|
||||
if link == 'update':
|
||||
return reverse('user_group_edit', args=[str(self.pk)])
|
||||
if link == 'delete':
|
||||
return reverse('user_group_delete', args=[str(self.pk)])
|
||||
return super(Group, self).get_absolute_url(link)
|
||||
url = reverse('user_group_view', args=[str(self.pk)])
|
||||
elif link == 'update':
|
||||
url = reverse('user_group_edit', args=[str(self.pk)])
|
||||
elif link == 'delete':
|
||||
url = reverse('user_group_delete', args=[str(self.pk)])
|
||||
else:
|
||||
url = super(Group, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
|
||||
class UsersAndGroupsToPersons(object):
|
||||
|
@ -5,6 +5,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.utils.models import AbsoluteUrlMixin
|
||||
from openslides.utils.utils import int_or_none
|
||||
|
||||
|
||||
@ -106,7 +107,7 @@ class SlideMixin(object):
|
||||
return context
|
||||
|
||||
|
||||
class ProjectorSlide(SlideMixin, models.Model):
|
||||
class ProjectorSlide(SlideMixin, AbsoluteUrlMixin, models.Model):
|
||||
"""
|
||||
Model for Slides, only for the projector. Also called custom slides.
|
||||
"""
|
||||
@ -118,19 +119,21 @@ class ProjectorSlide(SlideMixin, models.Model):
|
||||
text = models.TextField(null=True, blank=True, verbose_name=ugettext_lazy("Text"))
|
||||
weight = models.IntegerField(default=0, verbose_name=ugettext_lazy("Weight"))
|
||||
|
||||
def get_absolute_url(self, link='update'):
|
||||
if link == 'update':
|
||||
return reverse('customslide_edit', args=[str(self.pk)])
|
||||
if link == 'delete':
|
||||
return reverse('customslide_delete', args=[str(self.pk)])
|
||||
return super(ProjectorSlide, self).get_absolute_url(link)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
('can_manage_projector', ugettext_noop("Can manage the projector")),
|
||||
('can_see_projector', ugettext_noop("Can see the projector")),
|
||||
('can_see_dashboard', ugettext_noop("Can see the dashboard")),
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
def get_absolute_url(self, link='update'):
|
||||
if link == 'update':
|
||||
url = reverse('customslide_edit', args=[str(self.pk)])
|
||||
elif link == 'delete':
|
||||
url = reverse('customslide_delete', args=[str(self.pk)])
|
||||
else:
|
||||
url = super(ProjectorSlide, self).get_absolute_url(link)
|
||||
return url
|
||||
|
@ -16,3 +16,19 @@ class MinMaxIntegerField(models.IntegerField):
|
||||
defaults = {'min_value': self.min_value, 'max_value': self.max_value}
|
||||
defaults.update(kwargs)
|
||||
return super(MinMaxIntegerField, self).formfield(**defaults)
|
||||
|
||||
|
||||
class AbsoluteUrlMixin(object):
|
||||
"""
|
||||
Mixin that raises a ValueError if the name of an url was not found with
|
||||
get_absolute_url.
|
||||
|
||||
The Mixin has to be placed as last OpenSlides-Mixin before the django
|
||||
model class.
|
||||
"""
|
||||
|
||||
def get_absolute_url(self, link=None):
|
||||
"""
|
||||
Raises a ValueError.
|
||||
"""
|
||||
raise ValueError('Unknown Link "%s" for model "%s"' % (link, type(self)))
|
||||
|
@ -51,9 +51,14 @@ class Person(object):
|
||||
* delete
|
||||
|
||||
You should raise an 'ValueError', if your person does not have
|
||||
one of this links.
|
||||
one of this links, or use the AbsoluteURLMixin, which raises the
|
||||
ValueError for you.
|
||||
"""
|
||||
raise ValueError('This person object has no url.')
|
||||
try:
|
||||
url = super(Person, self).get_absolute_url(link)
|
||||
except AttributeError:
|
||||
raise ValueError('This person object has no url.')
|
||||
return url
|
||||
|
||||
|
||||
class Persons(object):
|
||||
|
@ -141,7 +141,8 @@ class UrlMixin(object):
|
||||
value = self.object.get_absolute_url(use_absolute_url_link)
|
||||
except AttributeError:
|
||||
raise ImproperlyConfigured(
|
||||
'No url to redirect to. See openslides.utils.views.UrlMixin for more details.')
|
||||
'No url to redirect to. See openslides.utils.views.UrlMixin '
|
||||
'for more details.')
|
||||
return value
|
||||
|
||||
def get_url_name_args(self):
|
||||
|
28
tests/utils/test_models.py
Normal file
28
tests/utils/test_models.py
Normal file
@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openslides.utils.models import AbsoluteUrlMixin
|
||||
from openslides.utils.test import TestCase
|
||||
|
||||
|
||||
class MyModel(AbsoluteUrlMixin):
|
||||
""""
|
||||
Model for testing
|
||||
"""
|
||||
def get_absolute_url(self, link='default'):
|
||||
if link == 'default' or link == 'known':
|
||||
url = 'my url'
|
||||
else:
|
||||
url = super(MyModel, self).get_absolute_url(link)
|
||||
return url
|
||||
|
||||
|
||||
class TestAbsoluteUrlMixin(TestCase):
|
||||
def test_get_absolute_url(self):
|
||||
my_object = MyModel()
|
||||
|
||||
self.assertEqual(my_object.get_absolute_url(), 'my url')
|
||||
self.assertEqual(my_object.get_absolute_url('known'), 'my url')
|
||||
self.assertRaisesMessage(
|
||||
ValueError,
|
||||
'Unknown Link "unknown" for model "<class \'tests.utils.test_models.MyModel\'>"',
|
||||
my_object.get_absolute_url, 'unknown')
|
Loading…
Reference in New Issue
Block a user