Python django.forms.ModelChoiceField() Examples

The following are 30 code examples of django.forms.ModelChoiceField(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module django.forms , or try the search function .
Example #1
Source File: forms.py    From registrasion with Apache License 2.0 11 votes vote down vote up
def staff_products_form_factory(user):
    ''' Creates a StaffProductsForm that restricts the available products to
    those that are available to a user. '''

    products = inventory.Product.objects.all()
    products = ProductController.available_products(user, products=products)

    product_ids = [product.id for product in products]
    product_set = inventory.Product.objects.filter(id__in=product_ids)

    class StaffProductsForm(forms.Form):
        ''' Form for allowing staff to add an item to a user's cart. '''

        product = forms.ModelChoiceField(
            widget=forms.Select,
            queryset=product_set,
        )

        quantity = forms.IntegerField(
            min_value=0,
        )

    return StaffProductsForm 
Example #2
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_overridable_choice_iterator(self):
        """
        Iterator defaults to ModelChoiceIterator and can be overridden with
        the iterator attribute on a ModelChoiceField subclass.
        """
        field = forms.ModelChoiceField(Category.objects.all())
        self.assertIsInstance(field.choices, ModelChoiceIterator)

        class CustomModelChoiceIterator(ModelChoiceIterator):
            pass

        class CustomModelChoiceField(forms.ModelChoiceField):
            iterator = CustomModelChoiceIterator

        field = CustomModelChoiceField(Category.objects.all())
        self.assertIsInstance(field.choices, CustomModelChoiceIterator) 
Example #3
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_prefetch_related_queryset(self):
        """
        ModelChoiceField should respect a prefetch_related() on its queryset.
        """
        blue = Colour.objects.create(name='blue')
        red = Colour.objects.create(name='red')
        multicolor_item = ColourfulItem.objects.create()
        multicolor_item.colours.add(blue, red)
        red_item = ColourfulItem.objects.create()
        red_item.colours.add(red)

        class ColorModelChoiceField(forms.ModelChoiceField):
            def label_from_instance(self, obj):
                return ', '.join(c.name for c in obj.colours.all())

        field = ColorModelChoiceField(ColourfulItem.objects.prefetch_related('colours'))
        with self.assertNumQueries(3):  # would be 4 if prefetch is ignored
            self.assertEqual(tuple(field.choices), (
                ('', '---------'),
                (multicolor_item.pk, 'blue, red'),
                (red_item.pk, 'red'),
            )) 
Example #4
Source File: vlan.py    From maas with GNU Affero General Public License v3.0 6 votes vote down vote up
def _set_up_relay_vlan(self):
        # Configure the relay_vlan fields to include only VLAN's that are
        # not already on a relay_vlan. If this is an update then it cannot
        # be itself or never set when dhcp_on is True.
        possible_relay_vlans = VLAN.objects.filter(relay_vlan__isnull=True)
        if self.instance is not None:
            possible_relay_vlans = possible_relay_vlans.exclude(
                id=self.instance.id
            )
            if self.instance.dhcp_on:
                possible_relay_vlans = VLAN.objects.none()
                if self.instance.relay_vlan is not None:
                    possible_relay_vlans = VLAN.objects.filter(
                        id=self.instance.relay_vlan.id
                    )
        self.fields["relay_vlan"] = forms.ModelChoiceField(
            queryset=possible_relay_vlans, required=False
        ) 
Example #5
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_choices_freshness(self):
        f = forms.ModelChoiceField(Category.objects.all())
        self.assertEqual(len(f.choices), 4)
        self.assertEqual(list(f.choices), [
            ('', '---------'),
            (self.c1.pk, 'Entertainment'),
            (self.c2.pk, 'A test'),
            (self.c3.pk, 'Third'),
        ])
        c4 = Category.objects.create(name='Fourth', slug='4th', url='4th')
        self.assertEqual(len(f.choices), 5)
        self.assertEqual(list(f.choices), [
            ('', '---------'),
            (self.c1.pk, 'Entertainment'),
            (self.c2.pk, 'A test'),
            (self.c3.pk, 'Third'),
            (c4.pk, 'Fourth'),
        ]) 
Example #6
Source File: forms.py    From hypha with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def make_role_reviewer_fields():
    role_fields = []
    staff_reviewers = User.objects.staff().only('full_name', 'pk')

    for role in ReviewerRole.objects.all().order_by('order'):
        field_name = 'role_reviewer_' + slugify(str(role))
        field = forms.ModelChoiceField(
            queryset=staff_reviewers,
            widget=Select2Widget(attrs={
                'data-placeholder': 'Select a reviewer',
            }),
            required=False,
            label=mark_safe(render_icon(role.icon) + f'{role.name} Reviewer'),
        )
        role_fields.append({
            'role': role,
            'field': field,
            'field_name': field_name,
        })

    return role_fields 
Example #7
Source File: tests.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_prefetch_related_queryset(self):
        """
        ModelChoiceField should respect a prefetch_related() on its queryset.
        """
        blue = Colour.objects.create(name='blue')
        red = Colour.objects.create(name='red')
        multicolor_item = ColourfulItem.objects.create()
        multicolor_item.colours.add(blue, red)
        red_item = ColourfulItem.objects.create()
        red_item.colours.add(red)

        class ColorModelChoiceField(forms.ModelChoiceField):
            def label_from_instance(self, obj):
                return ', '.join(c.name for c in obj.colours.all())

        field = ColorModelChoiceField(ColourfulItem.objects.prefetch_related('colours'))
        with self.assertNumQueries(3):  # would be 4 if prefetch is ignored
            self.assertEqual(tuple(field.choices), (
                ('', '---------'),
                (multicolor_item.pk, 'blue, red'),
                (red_item.pk, 'red'),
            )) 
Example #8
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_overridable_choice_iterator(self):
        """
        Iterator defaults to ModelChoiceIterator and can be overridden with
        the iterator attribute on a ModelChoiceField subclass.
        """
        field = forms.ModelChoiceField(Category.objects.all())
        self.assertIsInstance(field.choices, ModelChoiceIterator)

        class CustomModelChoiceIterator(ModelChoiceIterator):
            pass

        class CustomModelChoiceField(forms.ModelChoiceField):
            iterator = CustomModelChoiceIterator

        field = CustomModelChoiceField(Category.objects.all())
        self.assertIsInstance(field.choices, CustomModelChoiceIterator) 
Example #9
Source File: fields.py    From pasportaservo with GNU Affero General Public License v3.0 6 votes vote down vote up
def formfield(self, **kwargs):
        class SuggestiveModelChoiceFormField(forms.ModelChoiceField):
            widget = TextWithDatalistInput

            def __init__(self, *args, **kwargs):
                super().__init__(*args, **kwargs)
                self.empty_label = None

            def to_python(self, value):
                converted_value, is_invalid = _handle_invalid_choice(self, value, function='to_python')
                if is_invalid:
                    data = {'pk': value}
                    if self.to_field_name and self.to_field_name != 'pk':
                        data.update({self.to_field_name: value})
                        data['pk'] = -1
                    converted_value = self.queryset.model(**data)
                return converted_value

        defaults = {'form_class': SuggestiveModelChoiceFormField}
        defaults.update(kwargs)
        return super().formfield(**defaults) 
Example #10
Source File: admin.py    From django-seo with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def get_modelinstance_form(metadata_class):
    model_class = metadata_class._meta.get_model('modelinstance')

    # Restrict content type choices to the models set in seo_models
    content_types = get_seo_content_types(metadata_class._meta.seo_models)

    # Get a list of fields, with _content_type at the start
    important_fields = ['_content_type'] + ['_object_id'] + core_choice_fields(metadata_class)
    _fields = important_fields + list(fields_for_model(model_class,
                                                  exclude=important_fields).keys())

    class ModelMetadataForm(forms.ModelForm):
        _content_type = forms.ModelChoiceField(
            queryset=ContentType.objects.filter(id__in=content_types),
            empty_label=None,
            label=capfirst(_("model")),
        )

        _object_id = forms.IntegerField(label=capfirst(_("ID")))

        class Meta:
            model = model_class
            fields = _fields

    return ModelMetadataForm 
Example #11
Source File: forms.py    From conf_site with MIT License 6 votes vote down vote up
def build_presentation_field(self):
        kwargs = {}
        queryset = Presentation.objects.all()
        queryset = queryset.exclude(cancelled=True)
        queryset = queryset.order_by("proposal_base__pk")
        if self.slot.content:
            queryset = queryset.filter(
                Q(slot=None) | Q(pk=self.slot.content.pk)
            )
            kwargs["required"] = False
            kwargs["initial"] = self.slot.content
        else:
            queryset = queryset.filter(slot=None)
            kwargs["required"] = True
        kwargs["queryset"] = queryset
        return forms.ModelChoiceField(**kwargs) 
Example #12
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_disabled_modelchoicefield_has_changed(self):
        field = forms.ModelChoiceField(Author.objects.all(), disabled=True)
        self.assertIs(field.has_changed('x', 'y'), False) 
Example #13
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_choices_not_fetched_when_not_rendering(self):
        with self.assertNumQueries(1):
            field = forms.ModelChoiceField(Category.objects.order_by('-name'))
            self.assertEqual('Entertainment', field.clean(self.c1.pk).name) 
Example #14
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_num_queries(self):
        """
        Widgets that render multiple subwidgets shouldn't make more than one
        database query.
        """
        categories = Category.objects.all()

        class CategoriesForm(forms.Form):
            radio = forms.ModelChoiceField(queryset=categories, widget=forms.RadioSelect)
            checkbox = forms.ModelMultipleChoiceField(queryset=categories, widget=forms.CheckboxSelectMultiple)

        template = Template(
            '{% for widget in form.checkbox %}{{ widget }}{% endfor %}'
            '{% for widget in form.radio %}{{ widget }}{% endfor %}'
        )
        with self.assertNumQueries(2):
            template.render(Context({'form': CategoriesForm()})) 
Example #15
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_no_extra_query_when_accessing_attrs(self):
        """
        ModelChoiceField with RadioSelect widget doesn't produce unnecessary
        db queries when accessing its BoundField's attrs.
        """
        class ModelChoiceForm(forms.Form):
            category = forms.ModelChoiceField(Category.objects.all(), widget=forms.RadioSelect)

        form = ModelChoiceForm()
        field = form['category']  # BoundField
        template = Template('{{ field.name }}{{ field }}{{ field.help_text }}')
        with self.assertNumQueries(1):
            template.render(Context({'field': field})) 
Example #16
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_choices_not_fetched_when_not_rendering(self):
        with self.assertNumQueries(1):
            field = forms.ModelChoiceField(Category.objects.order_by('-name'))
            self.assertEqual('Entertainment', field.clean(self.c1.pk).name) 
Example #17
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_queryset_manager(self):
        f = forms.ModelChoiceField(Category.objects)
        self.assertEqual(len(f.choices), 4)
        self.assertEqual(list(f.choices), [
            ('', '---------'),
            (self.c1.pk, 'Entertainment'),
            (self.c2.pk, 'A test'),
            (self.c3.pk, 'Third'),
        ]) 
Example #18
Source File: viste.py    From jorvik with GNU General Public License v3.0 5 votes vote down vote up
def veicoli_veicolo_modifica_o_nuovo(request, me, pk=None):
    veicolo = None
    if pk is not None:
        veicolo = get_object_or_404(Veicolo, pk=pk)
        if not me.permessi_almeno(veicolo, MODIFICA):
            return redirect(ERRORE_PERMESSI)

    modulo = ModuloCreazioneVeicolo(request.POST or None, instance=veicolo)
    if pk is None:
        autoparchi, veicoli =_autoparchi_e_veicoli(me)
        modulo.fields["autoparco"] = forms.ModelChoiceField(queryset=autoparchi)
        modulo.fields["data_collocazione"] = forms.DateField(initial=datetime.date.today())
    if modulo.is_valid():
        v = modulo.save()

        if pk is None:
            collocazione = Collocazione(
                autoparco=modulo.cleaned_data["autoparco"],
                inizio=modulo.cleaned_data["data_collocazione"],
                veicolo=v
            )
            collocazione.save()
            return redirect("/veicoli/")
    contesto = {
        "modulo": modulo,
        "veicolo": veicolo,
    }

    return "veicoli_veicolo_modifica_o_nuovo.html", contesto 
Example #19
Source File: default_filters.py    From django-is-core with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def get_widget(self, request):
        """
        Table view is not able to get form field from reverse relation.
        Therefore this widget returns similar form field as direct relation (ModelChoiceField).
        Because there is used "RestrictedSelectWidget" it is returned textarea or selectox with choices according to
        count objects in the queryset.
        """
        return self._update_widget_choices(
            forms.ModelChoiceField(
                widget=RestrictedSelectWidget, queryset=self.field.related_model._default_manager.all()
            ).widget
        ) 
Example #20
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_choices(self):
        f = forms.ModelChoiceField(Category.objects.filter(pk=self.c1.id), required=False)
        self.assertIsNone(f.clean(''))
        self.assertEqual(f.clean(str(self.c1.id)).name, 'Entertainment')
        with self.assertRaises(ValidationError):
            f.clean('100')

        # len() can be called on choices.
        self.assertEqual(len(f.choices), 2)

        # queryset can be changed after the field is created.
        f.queryset = Category.objects.exclude(name='Third')
        self.assertEqual(list(f.choices), [
            ('', '---------'),
            (self.c1.pk, 'Entertainment'),
            (self.c2.pk, 'A test'),
        ])
        self.assertEqual(f.clean(self.c2.id).name, 'A test')
        with self.assertRaises(ValidationError):
            f.clean(self.c3.id)

        # Choices can be iterated repeatedly.
        gen_one = list(f.choices)
        gen_two = f.choices
        self.assertEqual(gen_one[2], (self.c2.pk, 'A test'))
        self.assertEqual(list(gen_two), [
            ('', '---------'),
            (self.c1.pk, 'Entertainment'),
            (self.c2.pk, 'A test'),
        ])

        # Overriding label_from_instance() to print custom labels.
        f.queryset = Category.objects.all()
        f.label_from_instance = lambda obj: 'category ' + str(obj)
        self.assertEqual(list(f.choices), [
            ('', '---------'),
            (self.c1.pk, 'category Entertainment'),
            (self.c2.pk, 'category A test'),
            (self.c3.pk, 'category Third'),
        ]) 
Example #21
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_disabled_modelchoicefield_has_changed(self):
        field = forms.ModelChoiceField(Author.objects.all(), disabled=True)
        self.assertIs(field.has_changed('x', 'y'), False) 
Example #22
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_disabled_modelchoicefield(self):
        class ModelChoiceForm(forms.ModelForm):
            author = forms.ModelChoiceField(Author.objects.all(), disabled=True)

            class Meta:
                model = Book
                fields = ['author']

        book = Book.objects.create(author=Writer.objects.create(name='Test writer'))
        form = ModelChoiceForm({}, instance=book)
        self.assertEqual(
            form.errors['author'],
            ['Select a valid choice. That choice is not one of the available choices.']
        ) 
Example #23
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_queryset_none(self):
        class ModelChoiceForm(forms.Form):
            category = forms.ModelChoiceField(queryset=None)

            def __init__(self, *args, **kwargs):
                super().__init__(*args, **kwargs)
                self.fields['category'].queryset = Category.objects.filter(slug__contains='test')

        form = ModelChoiceForm()
        self.assertCountEqual(form.fields['category'].queryset, [self.c2, self.c3]) 
Example #24
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_result_cache_not_shared(self):
        class ModelChoiceForm(forms.Form):
            category = forms.ModelChoiceField(Category.objects.all())

        form1 = ModelChoiceForm()
        self.assertCountEqual(form1.fields['category'].queryset, [self.c1, self.c2, self.c3])
        form2 = ModelChoiceForm()
        self.assertIsNone(form2.fields['category'].queryset._result_cache) 
Example #25
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_deepcopies_widget(self):
        class ModelChoiceForm(forms.Form):
            category = forms.ModelChoiceField(Category.objects.all())

        form1 = ModelChoiceForm()
        field1 = form1.fields['category']
        # To allow the widget to change the queryset of field1.widget.choices
        # without affecting other forms, the following must hold (#11183):
        self.assertIsNot(field1, ModelChoiceForm.base_fields['category'])
        self.assertIs(field1.widget.choices.field, field1) 
Example #26
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_choices_bool_empty_label(self):
        f = forms.ModelChoiceField(Category.objects.all(), empty_label='--------')
        Category.objects.all().delete()
        self.assertIs(bool(f.choices), True) 
Example #27
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_choices_bool(self):
        f = forms.ModelChoiceField(Category.objects.all(), empty_label=None)
        self.assertIs(bool(f.choices), True)
        Category.objects.all().delete()
        self.assertIs(bool(f.choices), False) 
Example #28
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_choices(self):
        f = forms.ModelChoiceField(Category.objects.filter(pk=self.c1.id), required=False)
        self.assertIsNone(f.clean(''))
        self.assertEqual(f.clean(str(self.c1.id)).name, 'Entertainment')
        with self.assertRaises(ValidationError):
            f.clean('100')

        # len() can be called on choices.
        self.assertEqual(len(f.choices), 2)

        # queryset can be changed after the field is created.
        f.queryset = Category.objects.exclude(name='Third')
        self.assertEqual(list(f.choices), [
            ('', '---------'),
            (self.c1.pk, 'Entertainment'),
            (self.c2.pk, 'A test'),
        ])
        self.assertEqual(f.clean(self.c2.id).name, 'A test')
        with self.assertRaises(ValidationError):
            f.clean(self.c3.id)

        # Choices can be iterated repeatedly.
        gen_one = list(f.choices)
        gen_two = f.choices
        self.assertEqual(gen_one[2], (self.c2.pk, 'A test'))
        self.assertEqual(list(gen_two), [
            ('', '---------'),
            (self.c1.pk, 'Entertainment'),
            (self.c2.pk, 'A test'),
        ])

        # Overriding label_from_instance() to print custom labels.
        f.queryset = Category.objects.all()
        f.label_from_instance = lambda obj: 'category ' + str(obj)
        self.assertEqual(list(f.choices), [
            ('', '---------'),
            (self.c1.pk, 'category Entertainment'),
            (self.c2.pk, 'category A test'),
            (self.c3.pk, 'category Third'),
        ]) 
Example #29
Source File: test_modelchoicefield.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_basics(self):
        f = forms.ModelChoiceField(Category.objects.all())
        self.assertEqual(list(f.choices), [
            ('', '---------'),
            (self.c1.pk, 'Entertainment'),
            (self.c2.pk, 'A test'),
            (self.c3.pk, 'Third'),
        ])
        with self.assertRaises(ValidationError):
            f.clean('')
        with self.assertRaises(ValidationError):
            f.clean(None)
        with self.assertRaises(ValidationError):
            f.clean(0)

        # Invalid types that require TypeError to be caught.
        with self.assertRaises(ValidationError):
            f.clean([['fail']])
        with self.assertRaises(ValidationError):
            f.clean([{'foo': 'bar'}])

        self.assertEqual(f.clean(self.c2.id).name, 'A test')
        self.assertEqual(f.clean(self.c3.id).name, 'Third')

        # Add a Category object *after* the ModelChoiceField has already been
        # instantiated. This proves clean() checks the database during clean()
        # rather than caching it at  instantiation time.
        c4 = Category.objects.create(name='Fourth', url='4th')
        self.assertEqual(f.clean(c4.id).name, 'Fourth')

        # Delete a Category object *after* the ModelChoiceField has already been
        # instantiated. This proves clean() checks the database during clean()
        # rather than caching it at instantiation time.
        Category.objects.get(url='4th').delete()
        msg = "['Select a valid choice. That choice is not one of the available choices.']"
        with self.assertRaisesMessage(ValidationError, msg):
            f.clean(c4.id) 
Example #30
Source File: fields.py    From djongo with GNU Affero General Public License v3.0 5 votes vote down vote up
def __init__(self, name, model_form_class, model_form_kw, model_container,
                 admin=None, request=None, *args, **kwargs):
        form_fields = []
        mdl_form_field_names = []
        widgets = []
        model_form_kwargs = model_form_kw.copy()

        try:
            model_form_kwargs['prefix'] = model_form_kwargs['prefix'] + '-' + name
        except KeyError:
            model_form_kwargs['prefix'] = name

        initial = kwargs.pop('initial', None)
        if initial:
            model_form_kwargs['initial'] = initial

        self.model_form_class = _get_model_form_class(
            model_form_class, model_container, admin, request)
        self.model_form_kwargs = model_form_kwargs
        self.admin = admin
        self.request = request

        error_messages = {
            'incomplete': 'Enter all required fields.',
        }

        self.model_form = self.model_form_class(**model_form_kwargs)
        for field_name, field in self.model_form.fields.items():
            if isinstance(field, (forms.ModelChoiceField, forms.ModelMultipleChoiceField)):
                continue
            elif isinstance(field, ArrayFormField):
                field.name = '%s-%s' % (self.model_form.prefix, field_name)
            form_fields.append(field)
            mdl_form_field_names.append(field_name)
            widgets.append(field.widget)

        widget = EmbeddedFormWidget(mdl_form_field_names, widgets)
        super().__init__(error_messages=error_messages, fields=form_fields,
                         widget=widget, require_all_fields=False, *args, **kwargs)