﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
32432	ModelForm does not respect ModelChoiceField's to_field_name attribute	gopackgo90	nobody	"This is the same issue mentioned in #17657 but for ModelChoiceField instead of ModelMultipleChoiceField. This bug is present in Django 2.2.18 and Django 3.1.6. The first two tests were taken directly from #17657 just to show that ModelMultipleChoiceField still works as expected and the equivalent ModelChoiceField tests are added after, the last of which fails:


{{{#!python
# models.py

from django.db import models


class Foo(models.Model):

    slug = models.CharField(max_length=40, unique=True)
    title = models.CharField(max_length=40, unique=True)

    def __str__(self):
        return self.title


class Bar(models.Model):

    foos = models.ManyToManyField(Foo)


class Baz(models.Model):

    foo = models.ForeignKey(Foo, on_delete=models.CASCADE)
}}}


{{{#!python
# tests.py

from django.test.testcases import TestCase
from django import forms
from .models import Foo, Bar, Baz


class TestModelRelationshipChoiceWithFieldName(TestCase):

    @classmethod
    def setUpTestData(cls):
        spam = Foo.objects.create(title=""Spam"", slug=""spam"")
        ham = Foo.objects.create(title=""Ham"", slug=""ham"")
        eggs = Foo.objects.create(title=""Eggs"", slug=""eggs"")
        cls.m2m_instance = Bar.objects.create()

        cls.m2m_instance.foos.add(spam)
        cls.m2m_instance.foos.add(ham)
        cls.m2m_instance.foos.add(eggs)

        cls.fk_instance = Baz.objects.create(foo=eggs)

    def test_multiple_without_field_name(self):

        class Form(forms.ModelForm):

            foos = forms.ModelMultipleChoiceField(Foo.objects.all())

            class Meta:
                model = Bar
                fields = '__all__'

        form = Form(instance=self.m2m_instance)

        self.assertEquals(
            str(form[""foos""]),
            '<select name=""foos"" required id=""id_foos"" multiple>\n'
            '  <option value=""1"" selected>Spam</option>\n\n'
            '  <option value=""2"" selected>Ham</option>\n\n'
            '  <option value=""3"" selected>Eggs</option>\n\n'
            '</select>'
        )

    def test_multiple_with_field_name(self):

        class Form(forms.ModelForm):

            foos = forms.ModelMultipleChoiceField(Foo.objects.all(), to_field_name=""slug"")

            class Meta:
                model = Bar
                fields = '__all__'

        form = Form(instance=self.m2m_instance)

        # Fixed in #17657, options weren't selected.
        self.assertEquals(
            str(form[""foos""]),
            '<select name=""foos"" required id=""id_foos"" multiple>\n'
            '  <option value=""spam"" selected>Spam</option>\n\n'
            '  <option value=""ham"" selected>Ham</option>\n\n'
            '  <option value=""eggs"" selected>Eggs</option>\n\n'
            '</select>'
        )

    def test_one_without_field_name(self):

        class Form(forms.ModelForm):

            foo = forms.ModelChoiceField(Foo.objects.all())

            class Meta:
                model = Baz
                fields = '__all__'

        form = Form(instance=self.fk_instance)

        self.assertEquals(
            str(form[""foo""]),
            '<select name=""foo"" required id=""id_foo"">\n'
            '  <option value="""">---------</option>\n\n'
            '  <option value=""1"">Spam</option>\n\n'
            '  <option value=""2"">Ham</option>\n\n'
            '  <option value=""3"" selected>Eggs</option>\n\n'
            '</select>'
        )

    def test_one_with_field_name(self):

        class Form(forms.ModelForm):

            foo = forms.ModelChoiceField(Foo.objects.all(), to_field_name=""slug"")

            class Meta:
                model = Baz
                fields = '__all__'

        form = Form(instance=self.fk_instance)

        # Fails! Option isn't selected.
        self.assertEquals(
            str(form[""foo""]),
            '<select name=""foo"" required id=""id_foo"">\n'
            '  <option value="""">---------</option>\n\n'
            '  <option value=""spam"">Spam</option>\n\n'
            '  <option value=""ham"">Ham</option>\n\n'
            '  <option value=""eggs"" selected>Eggs</option>\n\n'
            '</select>'
        )
}}}

"	Uncategorized	new	Forms	3.1	Normal				Unreviewed	0	0	0	0	0	0
