Пример #1
0
    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        """
        Get a form Field for a ManyToManyField.
        """
        # If it uses an intermediary model that isn't auto created, don't show
        # a field in admin.
        if hasattr(db_field, 'through'
                   ) and not db_field.remote_field.through._meta.auto_created:
            return None
        db = kwargs.get('using')

        if db_field.name in self.raw_id_fields:
            kwargs['widget'] = widgets.ManyToManyRawIdWidget(
                db_field.remote_field, self.admin_site, using=db)
            kwargs['help_text'] = ''
        elif db_field.name in (list(self.filter_vertical) +
                               list(self.filter_horizontal)):
            kwargs['widget'] = widgets.FilteredSelectMultiple(
                db_field.verbose_name, db_field.name in self.filter_vertical)

        if 'queryset' not in kwargs:
            queryset = self.get_field_queryset(db, db_field, request)
            if queryset is not None:
                kwargs['queryset'] = queryset

        form_field = db_field.formfield(**kwargs)
        if isinstance(form_field.widget, SelectMultiple) and not isinstance(
                form_field.widget, CheckboxSelectMultiple):
            msg = _(
                'Hold down "Control", or "Command" on a Mac, to select more than one.'
            )
            help_text = form_field.help_text
            form_field.help_text = string_concat(help_text, ' ',
                                                 msg) if help_text else msg
        return form_field
Пример #2
0
    def test_render(self):
        band = models.Band.objects.create(name='Linkin Park')

        m1 = models.Member.objects.create(name='Chester')
        m2 = models.Member.objects.create(name='Mike')
        band.members.add(m1, m2)
        rel = models.Band._meta.get_field('members').rel

        w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
        self.assertEqual(
            conditional_escape(w.render('test', [m1.pk, m2.pk], attrs={})),
            '<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" /><a href="/widget_admin/admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="/static/admin/img/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk, m2pk=m2.pk)
        )

        self.assertEqual(
            conditional_escape(w.render('test', [m1.pk])),
            '<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField" /><a href="/widget_admin/admin_widgets/member/" class="related-lookup" id="lookup_id_test" onclick="return showRelatedObjectLookupPopup(this);"> <img src="%(ADMIN_MEDIA_PREFIX)simg/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % dict(admin_media_prefix(), m1pk=m1.pk)
        )

        self.assertEqual(w._has_changed(None, None), False)
        self.assertEqual(w._has_changed([], None), False)
        self.assertEqual(w._has_changed(None, [u'1']), True)
        self.assertEqual(w._has_changed([1, 2], [u'1', u'2']), False)
        self.assertEqual(w._has_changed([1, 2], [u'1']), True)
        self.assertEqual(w._has_changed([1, 2], [u'1', u'3']), True)
Пример #3
0
def adminform_formfield(db_field, **kwargs):
    """
    Enables admin form widgets when used as formfield_callback.
    Use with CAUTION as using admin widgets is at your risk :)
    """
    if db_field.choices:
        return db_field.formfield(**kwargs)

    if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
        if isinstance(db_field, models.ForeignKey):
            kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)

        elif isinstance(db_field, models.ManyToManyField):
            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel)
        formfield = db_field.formfield(**kwargs)

        if formfield:
            #            related_modeladmin = admin.site._registry.get(db_field.rel.to)
            #            can_add_related = bool(related_modeladmin and
            #                            related_modeladmin.has_add_permission(request))
            formfield.widget = widgets.RelatedFieldWidgetWrapper(
                formfield.widget,
                db_field.rel,
                admin.site,
                can_add_related=True)

    for klass in db_field.__class__.mro():
        if klass in FORMFIELD_FOR_DBFIELD_DEFAULTS:
            kwargs = dict(FORMFIELD_FOR_DBFIELD_DEFAULTS[klass], **kwargs)
            return db_field.formfield(**kwargs)

    return db_field.formfield(**kwargs)
Пример #4
0
class ManyToManyRawIdWidgetForm(forms.Form):
    description = "ManyToManyRawIdWidget"

    field1 = forms.ModelMultipleChoiceField(
        help_text='default', queryset=Permission.objects.all(),
        widget=widgets.ManyToManyRawIdWidget(
            rel=Group._meta.get_field('permissions').remote_field,
            admin_site=admin_site))
Пример #5
0
    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        """
        Get a form Field for a ManyToManyField.
        """
        db = kwargs.get('using')

        if db_field.name in self.raw_id_fields:
            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel, using=db)
            kwargs['help_text'] = ''
        elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
            kwargs['widget'] = widgets.FilteredSelectMultiple(pretty_name(db_field.name), (db_field.name in self.filter_vertical))

        return db_field.formfield(**kwargs)
Пример #6
0
    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        """
        Get a form Field for a ManyToManyField.
        """
        # If it uses an intermediary model, don't show field in admin.
        if db_field.rel.through is not None:
            return None

        if db_field.name in self.raw_id_fields:
            kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel)
            kwargs['help_text'] = ''
        elif db_field.name in (list(self.filter_vertical) +
                               list(self.filter_horizontal)):
            kwargs['widget'] = widgets.FilteredSelectMultiple(
                db_field.verbose_name, (db_field.name in self.filter_vertical))

        return db_field.formfield(**kwargs)
Пример #7
0
    def formfield_for_manytomany_modified(self, db_field, request, **kwargs):
        """
        Get a form Field for a ManyToManyField.
        """
        # If it uses an intermediary model that isn't auto created, don't show
        # a field in admin.
        if not db_field.remote_field.through._meta.auto_created:  # pylint: disable=W0212
            return None
        db = kwargs.get('using')  # pylint: disable=C0103

        autocomplete_fields = self.get_autocomplete_fields(request)
        # just added this line...
        if 'widget' not in kwargs:
            if db_field.name in autocomplete_fields:
                kwargs['widget'] = AutocompleteSelectMultiple(
                    db_field.remote_field, self.admin_site, using=db)
            elif db_field.name in self.raw_id_fields:
                kwargs['widget'] = widgets.ManyToManyRawIdWidget(
                    db_field.remote_field, self.admin_site, using=db)
            elif db_field.name in [
                    *self.filter_vertical, *self.filter_horizontal
            ]:
                kwargs['widget'] = widgets.FilteredSelectMultiple(
                    db_field.verbose_name, db_field.name
                    in self.filter_vertical)

        if 'queryset' not in kwargs:
            queryset = self.get_field_queryset(db, db_field, request)
            if queryset is not None:
                kwargs['queryset'] = queryset

        form_field = db_field.formfield(**kwargs)
        if isinstance(form_field.widget, SelectMultiple) and not isinstance(
                form_field.widget,
            (CheckboxSelectMultiple, AutocompleteSelectMultiple)):
            msg = _(
                'Hold down "Control", or "Command" on a Mac, to select more than one.'
            )
            help_text = form_field.help_text
            form_field.help_text = format_lazy('{0} {1}', help_text,
                                               msg) if help_text else msg
        return form_field
Пример #8
0
    def test_m2m_related_model_not_in_admin(self):
        # M2M relationship with model not registered with admin site. Raw ID
        # widget should have no magnifying glass link. See #16542
        consultor1 = models.Advisor.objects.create(name='Rockstar Techie')

        c1 = models.Company.objects.create(name='Doodle')
        c2 = models.Company.objects.create(name='Pear')
        consultor1.companies.add(c1, c2)
        rel = models.Advisor._meta.get_field('companies').rel

        w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
        self.assertEqual(
            conditional_escape(w.render('company_widget1', [c1.pk, c2.pk], attrs={})),
            '<input type="text" name="company_widget1" value="%(c1pk)s,%(c2pk)s" />' % {'c1pk': c1.pk, 'c2pk': c2.pk}
        )

        self.assertEqual(
            conditional_escape(w.render('company_widget2', [c1.pk])),
            '<input type="text" name="company_widget2" value="%(c1pk)s" />' % {'c1pk': c1.pk}
        )
Пример #9
0
    def test_render(self):
        band = models.Band.objects.create(name='Linkin Park')

        m1 = models.Member.objects.create(name='Chester')
        m2 = models.Member.objects.create(name='Mike')
        band.members.add(m1, m2)
        rel = models.Band._meta.get_field('members').rel

        w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
        self.assertHTMLEqual(
            w.render('test', [m1.pk, m2.pk], attrs={}), (
                '<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField" />'
                '<a href="/admin_widgets/member/" class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
            ) % dict(m1pk=m1.pk, m2pk=m2.pk)
        )

        self.assertHTMLEqual(
            w.render('test', [m1.pk]), (
                '<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField">'
                '<a href="/admin_widgets/member/" class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
            ) % dict(m1pk=m1.pk)
        )
Пример #10
0
    def formfield_for_dbfield(self, db_field, **kwargs):
        """
        Hook for specifying the form Field instance for a given database Field
        instance.

        If kwargs are given, they're passed to the form Field's constructor.
        """
        # For DateTimeFields, use a special field and widget.
        if isinstance(db_field, models.DateTimeField):
            kwargs['form_class'] = forms.SplitDateTimeField
            kwargs['widget'] = widgets.AdminSplitDateTime()
            return db_field.formfield(**kwargs)

        # For DateFields, add a custom CSS class.
        if isinstance(db_field, models.DateField):
            kwargs['widget'] = widgets.AdminDateWidget
            return db_field.formfield(**kwargs)

        # For TimeFields, add a custom CSS class.
        if isinstance(db_field, models.TimeField):
            kwargs['widget'] = widgets.AdminTimeWidget
            return db_field.formfield(**kwargs)

        # For FileFields and ImageFields add a link to the current file.
        if isinstance(db_field, models.ImageField) or isinstance(
                db_field, models.FileField):
            kwargs['widget'] = widgets.AdminFileWidget
            return db_field.formfield(**kwargs)

        # For ForeignKey or ManyToManyFields, use a special widget.
        if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
            if isinstance(
                    db_field,
                    models.ForeignKey) and db_field.name in self.raw_id_fields:
                kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)
            elif isinstance(
                    db_field,
                    models.ForeignKey) and db_field.name in self.radio_fields:
                kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                    'class':
                    get_ul_class(self.radio_fields[db_field.name]),
                })
                kwargs['empty_label'] = db_field.blank and _('None') or None
            else:
                if isinstance(db_field, models.ManyToManyField):
                    if db_field.name in self.raw_id_fields:
                        kwargs['widget'] = widgets.ManyToManyRawIdWidget(
                            db_field.rel)
                        kwargs['help_text'] = ''
                    elif db_field.name in (list(self.filter_vertical) +
                                           list(self.filter_horizontal)):
                        kwargs['widget'] = widgets.FilteredSelectMultiple(
                            db_field.verbose_name,
                            (db_field.name in self.filter_vertical))
            # Wrap the widget's render() method with a method that adds
            # extra HTML to the end of the rendered output.
            formfield = db_field.formfield(**kwargs)
            # Don't wrap raw_id fields. Their add function is in the popup window.
            if not db_field.name in self.raw_id_fields:
                formfield.widget = widgets.RelatedFieldWidgetWrapper(
                    formfield.widget, db_field.rel, self.admin_site)
            return formfield

        if db_field.choices and db_field.name in self.radio_fields:
            kwargs['widget'] = widgets.AdminRadioSelect(
                choices=db_field.get_choices(include_blank=db_field.blank,
                                             blank_choice=[('', _('None'))]),
                attrs={
                    'class': get_ul_class(self.radio_fields[db_field.name]),
                })

        # For any other type of field, just call its formfield() method.
        return db_field.formfield(**kwargs)
Пример #11
0
    def formfield_for_dbfield(self, db_field, **kwargs):
        """
        Hook for specifying the form Field instance for a given database Field
        instance.

        If kwargs are given, they're passed to the form Field's constructor.
        """

        # If the field specifies choices, we don't need to look for special
        # admin widgets - we just need to use a select widget of some kind.
        if db_field.choices:
            if db_field.name in self.radio_fields:
                # If the field is named as a radio_field, use a RadioSelect
                kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                    'class':
                    get_ul_class(self.radio_fields[db_field.name]),
                })
                kwargs['choices'] = db_field.get_choices(
                    include_blank=db_field.blank,
                    blank_choice=[('', _('None'))])
                return db_field.formfield(**kwargs)
            else:
                # Otherwise, use the default select widget.
                return db_field.formfield(**kwargs)

        # For DateTimeFields, use a special field and widget.
        if isinstance(db_field, models.DateTimeField):
            kwargs['form_class'] = forms.SplitDateTimeField
            kwargs['widget'] = widgets.AdminSplitDateTime()
            return db_field.formfield(**kwargs)

        # For DateFields, add a custom CSS class.
        if isinstance(db_field, models.DateField):
            kwargs['widget'] = widgets.AdminDateWidget
            return db_field.formfield(**kwargs)

        # For TimeFields, add a custom CSS class.
        if isinstance(db_field, models.TimeField):
            kwargs['widget'] = widgets.AdminTimeWidget
            return db_field.formfield(**kwargs)

        # For TextFields, add a custom CSS class.
        if isinstance(db_field, models.TextField):
            kwargs['widget'] = widgets.AdminTextareaWidget
            return db_field.formfield(**kwargs)

        # For URLFields, add a custom CSS class.
        if isinstance(db_field, models.URLField):
            kwargs['widget'] = widgets.AdminURLFieldWidget
            return db_field.formfield(**kwargs)

        # For IntegerFields, add a custom CSS class.
        if isinstance(db_field, models.IntegerField):
            kwargs['widget'] = widgets.AdminIntegerFieldWidget
            return db_field.formfield(**kwargs)

        # For CommaSeparatedIntegerFields, add a custom CSS class.
        if isinstance(db_field, models.CommaSeparatedIntegerField):
            kwargs['widget'] = widgets.AdminCommaSeparatedIntegerFieldWidget
            return db_field.formfield(**kwargs)

        # For TextInputs, add a custom CSS class.
        if isinstance(db_field, models.CharField):
            kwargs['widget'] = widgets.AdminTextInputWidget
            return db_field.formfield(**kwargs)

        # For FileFields and ImageFields add a link to the current file.
        if isinstance(db_field, models.ImageField) or isinstance(
                db_field, models.FileField):
            kwargs['widget'] = widgets.AdminFileWidget
            return db_field.formfield(**kwargs)

        # For ForeignKey or ManyToManyFields, use a special widget.
        if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
            if isinstance(
                    db_field,
                    models.ForeignKey) and db_field.name in self.raw_id_fields:
                kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)
            elif isinstance(
                    db_field,
                    models.ForeignKey) and db_field.name in self.radio_fields:
                kwargs['widget'] = widgets.AdminRadioSelect(attrs={
                    'class':
                    get_ul_class(self.radio_fields[db_field.name]),
                })
                kwargs['empty_label'] = db_field.blank and _('None') or None
            else:
                if isinstance(db_field, models.ManyToManyField):
                    # If it uses an intermediary model, don't show field in admin.
                    if db_field.rel.through is not None:
                        return None
                    elif db_field.name in self.raw_id_fields:
                        kwargs['widget'] = widgets.ManyToManyRawIdWidget(
                            db_field.rel)
                        kwargs['help_text'] = ''
                    elif db_field.name in (list(self.filter_vertical) +
                                           list(self.filter_horizontal)):
                        kwargs['widget'] = widgets.FilteredSelectMultiple(
                            db_field.verbose_name,
                            (db_field.name in self.filter_vertical))
            # Wrap the widget's render() method with a method that adds
            # extra HTML to the end of the rendered output.
            formfield = db_field.formfield(**kwargs)
            # Don't wrap raw_id fields. Their add function is in the popup window.
            if not db_field.name in self.raw_id_fields:
                # formfield can be None if it came from a OneToOneField with
                # parent_link=True
                if formfield is not None:
                    formfield.widget = widgets.RelatedFieldWidgetWrapper(
                        formfield.widget, db_field.rel, self.admin_site)
            return formfield

        # For any other type of field, just call its formfield() method.
        return db_field.formfield(**kwargs)
Пример #12
0
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        """
        Get a form Field for a ManyToManyField.
        """
        # If it uses an intermediary model that isn't auto created, don't show
        # a field in admin.
        if not db_field.remote_field.through._meta.auto_created:
            return None
        db = kwargs.get("using")

        if "widget" not in kwargs:
            autocomplete_fields = self.get_autocomplete_fields(request)
            if db_field.name in autocomplete_fields:

                # BEGIN CUSTOMIZATION
                kwargs["widget"] = SemanticAutocompleteSelectMultiple(
                    db_field,
                    self.admin_site,
                    using=db,
                )
                # END CUSTOMIZATION

            elif db_field.name in self.raw_id_fields:
                kwargs["widget"] = widgets.ManyToManyRawIdWidget(
                    db_field.remote_field,
                    self.admin_site,
                    using=db,
                )
            elif db_field.name in [
                    *self.filter_vertical, *self.filter_horizontal
            ]:
                # TODO
                kwargs["widget"] = widgets.FilteredSelectMultiple(
                    db_field.verbose_name, db_field.name
                    in self.filter_vertical)
        if "queryset" not in kwargs:
            queryset = self.get_field_queryset(db, db_field, request)
            if queryset is not None:
                kwargs["queryset"] = queryset

        # BEGIN CUSTOMIZATION
        if "widget" not in kwargs:
            kwargs["widget"] = SemanticSelectMultiple()
        # END CUSTOMIZATION

        form_field = db_field.formfield(**kwargs)

        # BEGIN CUSTOMIZATION
        # if isinstance(form_field.widget, SemanticSelectMultiple) and not isinstance(
        #     form_field.widget,
        #     (SemanticCheckboxSelectMultiple, SemanticAutocompleteSelectMultiple),
        # ):
        #     msg = _(
        #         "Hold down “Control”, or “Command” on a Mac, to select more than one."
        #     )
        #     help_text = form_field.help_text
        #     form_field.help_text = (
        #         format_lazy("{} {}", help_text, msg) if help_text else msg
        #     )
        # END CUSTOMIZATION

        return form_field