Пример #1
0
def event_selections_edit_option(request, event_pk, group_pk, option_pk):

    event = get_object_or_404(Event, pk=event_pk)
    group = get_object_or_404(event.optiongroups, pk=group_pk)
    _option = get_object_or_404(group.options, pk=option_pk)

    type_manager = type_manager_factory(_option)
    stype_manager = stype_manager_factory(_option)

    # fetch the correct "overloaded" option
    option = type_manager.get_model().objects.get(pk=_option.pk)

    view = stype_manager.get_update_view()

    return view(request, event, group, instance=option)
Пример #2
0
    def copy_and_mutate_self(self):

        from selvbetjening.core.events.options.typemanager import type_manager_factory

        optiongroups = list(self.optiongroup_set.all())

        self.pk = None
        self.title = '%s (copy)' % self.title
        self.is_visible = False
        self.save()

        for group in optiongroups:

            options = list(group.options)

            group.pk = None
            group.save()

            self.optiongroup_set.add(group)

            for _option in options:

                suboptions = list(_option.suboptions)

                # fetch the correct "overloaded" option
                type_manager = type_manager_factory(_option)
                option = type_manager.get_model().objects.get(pk=_option.pk)

                # copy option in a way that is compatible with inheritance
                from django.db.models import AutoField
                fields = dict([(f.name, getattr(option, f.name))
                               for f in option._meta.fields
                                   if not isinstance(f, AutoField) and\
                                       not f in option._meta.parents.values()])
                new_obj = option.__class__(**fields)
                new_obj.pk = None
                new_obj.save()

                group.option_set.add(new_obj)

                for suboption in suboptions:

                    suboption.pk = None
                    suboption.save()

                    new_obj.suboption_set.add(suboption)
Пример #3
0
def event_selections_delete_option(request, event_pk, group_pk, option_pk):

    event = get_object_or_404(Event, pk=event_pk)
    group = get_object_or_404(event.optiongroups, pk=group_pk)
    _option = get_object_or_404(group.options, pk=option_pk)

    type_manager = type_manager_factory(_option)

    # fetch the correct "overloaded" option
    option = type_manager.get_model().objects.get(pk=_option.pk)

    context = {
        "sadmin2_menu_main_active": "events",
        "sadmin2_breadcrumbs_active": "event_selections_delete_option",
        "sadmin2_menu_tab": menu.sadmin2_menu_tab_event,
        "sadmin2_menu_tab_active": "settings",
        "event": event,
        "option_group": group,
        "option": option,
    }

    # Check if we are allowed to delete this object

    selection_count = Selection.objects.filter(option=option).count()

    if selection_count > 0:
        context["selection_count"] = selection_count

        return render(request, "sadmin2/event/selection_option_delete_not_possible.html", context)

    # If yes, then ...

    if request.method == "POST":
        option.delete()

        messages.success(request, _("Option %s deleted" % option.name))
        return HttpResponseRedirect(reverse("sadmin2:event_settings_selections", kwargs={"event_pk": event.pk}))

    context["obj_type"] = "Option"
    context["to_be_deleted"] = _get_deleted_objects([option])

    return render(request, "sadmin2/generic/delete.html", context)
Пример #4
0
def dynamic_selections_form_factory(scope, option_group_instance, helper_factory=None, options=None):

    if options is None:
        options = dynamic_options(scope, option_group_instance.event, option_group=option_group_instance)
        options = [option[0] for option in options]

    # TODO use selections from dynamic options

    def init(self, *args, **kwargs):
        self.attendee = kwargs.pop('attendee', None)
        self.attendee = kwargs.pop('instance', self.attendee)
        self.user = kwargs.pop('user')

        if self.attendee is not None:
            self.user = self.attendee.user  # force the usage of attendee.user

        if self.attendee is not None:
            initial = {}

            selections = kwargs.pop('selections', None)

            if selections is None:
                selections = self.attendee.selection_set.all().select_related('option')

            for selection in selections:
                field_id = _pack_id('option', selection.option.pk)

                if field_id in self.type_widgets:
                    initial[field_id] = self.type_widgets[field_id].initial_value(selection)

            kwargs['initial'] = initial

        super(forms.Form, self).__init__(*args, **kwargs)

        for field_id, type_widget in self.type_widgets.items():

            if hasattr(type_widget, 'update_choices'):
                type_widget.update_choices(self.user, self.attendee)
                self.fields[field_id].choices = type_widget.choices

            if self.attendee is not None and not type_widget.is_editable(self.attendee):
                self.fields[field_id].widget.attrs['disabled'] = "disabled"

    def save(self, *args, **kwargs):
        attendee = kwargs.pop('attendee', self.attendee)
        assert attendee is not None

        for key, save_callback in self.save_callbacks.items():
            save_callback(attendee, self.cleaned_data.get(key, None))

    def clean_callback(field_id, related_field, type_manager_clean_callback):
        def inner(self):

            # If we have a related field, then erase the value if the related field is not selected.
            if related_field is not None:

                # Related field is readonly and is not set "initially"
                if related_field in self.readonly and not self.initial.get(related_field, False):
                    return None

                if related_field not in self.readonly and not self.cleaned_data.get(related_field, False):
                    return None

            return type_manager_clean_callback(self.cleaned_data.get(field_id, None))

        return inner

    @staticmethod
    def is_empty():
        return len(options) == 0

    def clean(self):
        cleaned_data = super(forms.Form, self).clean()

        if scope == SCOPE.SADMIN:
            # Do not enforce max/min for admin
            return cleaned_data

        if option_group_instance.minimum_selected <= 0 and option_group_instance.maximum_selected <= 0:
            return cleaned_data

        selected = 0

        for option in options:
            field_id = _pack_id('option', option.pk)

            if getattr(option, scope):
                # field is editable
                value = cleaned_data.get(field_id, None)
            else:
                value = self.initial.get(field_id, None)

            selected += 1 if self._selected_callbacks[field_id](value) else 0

        if option_group_instance.minimum_selected > 0 and selected < option_group_instance.minimum_selected:
            raise forms.ValidationError(ungettext_lazy('You must select at least %d option.',
                                                       'You must select at least %d options.',
                                                       option_group_instance.minimum_selected) % option_group_instance.minimum_selected)

        if 0 < option_group_instance.maximum_selected < selected:
            raise forms.ValidationError(ungettext_lazy('You must select at most %d option.',
                                                       'You must select at most %d options.',
                                                       option_group_instance.maximum_selected) % option_group_instance.maximum_selected)

        return cleaned_data

    fields = {
        '__init__': init,
        'save': save,
        'is_empty': is_empty,
        'clean': clean,
        'save_callbacks': {},
        '_selected_callbacks': {},
        'type_widgets': {},
        'readonly': []
    }

    for option in options:
        widget = type_manager_factory(option).get_widget(scope, option)
        field_id = _pack_id('option', option.pk)

        related_field = None
        attrs = None

        if option.depends_on is not None:
            related_field = _pack_id('option', option.depends_on.pk)
            attrs = {'data-depends-on': related_field}

        fields[field_id] = widget.get_field(attrs=attrs)
        fields['_selected_callbacks'][field_id] = widget.selected_callback

        if scope == SCOPE.SADMIN or getattr(option, scope):  # The edit scope bit is set
            fields['clean_%s' % field_id] = clean_callback(field_id, related_field, widget.clean_callback)
            fields['save_callbacks'][field_id] = widget.save_callback
        else:  # The edit bit is not set, this is a view only option
            fields['clean_%s' % field_id] = lambda self: None
            fields['save_callbacks'][field_id] = lambda attendee, value: None

            if not hasattr(fields[field_id].widget, 'CANT_DISABLE'):
                fields[field_id].widget.attrs['disabled'] = 'disabled'
                fields[field_id].required = False  # If we don't do this Django will err because of missing POST data
                fields['readonly'].append(field_id)

        fields['type_widgets'][field_id] = widget

    if helper_factory is not None:
        fields['helper'] = helper_factory(option_group_instance,
                                          [_pack_id('option', option.pk) for option in options])

    return type('OptionGroupSelectionsForm', (forms.Form,), fields)