Django Question 'ModelChoiceField' object has no attribute 'use_required_attribute'

734 views Asked by At

Dears, I met a problem in Django. There is an error about 'ModelChoiceField' object has no attribute 'use_required_attribute' and I don't know where I made mistake.

My goal is to make my submit customizing form but I couldn't understand how CBV in Django can reach this goal, so I went back to use forms.py and FBV in Django. But my fields in form model have foreign keys to refer other models. I used forms.ModelChoiceField and expected to solve foreign key problem but it doesn't work and show this error.

Thank you for reading and hope someone can help me to solve it.

Here are my code:

forms.py

    from django import forms
    from .models import Case
    from school_app.models import School
    from student_app.models import Student
    class CaseModelForm(forms.ModelForm):
    
        class Meta:
            model = Case
            fields='__all__'
            widgets = {
                'name' : forms.ModelChoiceField(queryset=Student.objects.all()),
                'phone' : forms.TextInput(),
                'school' :forms.ModelChoiceField(queryset=School.objects.all())
}

models.py

    from django.db import models
    from django.urls import reverse
    import datetime,time
    from school_app.models import School
    from student_app.models import Student
    # Create your models here.
    class Case(models.Model):
        name=models.ForeignKey(Student,related_name='case_student_name',on_delete=models.CASCADE,verbose_name="姓名")
        phone=models.CharField(verbose_name="電話",blank=False,max_length=256)
        school=school=models.ForeignKey(School,related_name='case_school',on_delete=models.CASCADE,verbose_name="學校")

views.py

def CaseFormView(request):
    print("CaseForm")
    form_cus = CaseModelForm()
    if request.method == "POST":
        form = CaseModelForm(request.POST)
        if form.is_valid():
            form.save()
        return redirect("/")

    context={
        'form_cus': form_cus
    }
    return render(request, 'case_app/case_form.html',context)

urls.py

from student_app import views
from django.urls import path
app_name = 'student_app'

urlpatterns=[
    path('', views.StudentListView.as_view(),name='list'),
    path('<int:pk>/', views.StudentDetailView.as_view(), name='detail'),
    path('create/',views.StudentCreateView.as_view(), name='create')]

case_form.html

<form method="post">
    {% csrf_token %}
    
    <div class="form-group">
        <div class="form-group col-md-6">
            <label>{{form_cus.name.label}}</label>

            {{form_cus.name}}
        </div>
        <div class="form-group col-md-6">
            <label>{{form_cus.school.label}}</label>

            {{form_cus.school}}
        </div>
        {{form_cus}}
    <input type="submit" class="btn btn-primary" value="提交"> 
       
    </div>
    {% if not form.instance.pk %}
    <a class='btn btn-secondary' href="{% url 'case_app:list' %}">取消</a>
    {% else %}
    <a class='btn btn-secondary' href="{% url 'case_app:detail' pk=form.instance.pk %}">取消</a>
    {% endif %}
</form>

Thank you!

1

There are 1 answers

6
willeM_ Van Onsem On BEST ANSWER

A ModelChoiceField is not a widget, it is a form field, you thus can implement this as:

from django import forms
from .models import Case
from school_app.models import School
from student_app.models import Student

class CaseModelForm(forms.ModelForm):
    school = forms.ModelChoiceField(queryset=School.objects.all())
    name = forms.ModelChoiceField(queryset=Student.objects.all())

    class Meta:
        model = Case
        fields='__all__'
        widgets = {
            'phone' : forms.TextInput(),    
        }

Since school and name are however ForeignKeys in your Case model, you do not need to specify these: we can implement the CaseModelForm with:

from django import forms
from .models import Case
from school_app.models import School
from student_app.models import Student

class CaseModelForm(forms.ModelForm):
    # no school/name field
    class Meta:
        model = Case
        fields='__all__'
        widgets = {
            'phone' : forms.TextInput(),    
        }