首页 > 解决方案 > Django:我在 B 上有一个带有 FK 的对象 A。如何以 A 的形式在下拉列表中显示 B 中的列?

问题描述

我收到错误“为会话指定的未知字段(主题、主题)”。我正在尝试在我的 sessionForm 中为主题和主题建立一个下拉列表。

我的模型如下:

class Subject(models.Model):
    name = models.CharField(max_length = 30, primary_key = True)       

    def __str__(self):
      return self.name

    class Meta:
        db_table = 'subjects'  

class Module(models.Model):
  topic   = models.CharField(max_length = 200)  
  subject = models.ForeignKey(Subject, on_delete=models.CASCADE)  

  def __str__(self):
    return self.topic + ' in ' + self.subject.name

  class Meta:
        db_table = 'modules'         

class Session(models.Model):
   grade_level  = models.CharField(max_length = 30)
   num_students = models.IntegerField(default=0)
   session_dt = models.DateTimeField() 
   module = models.ForeignKey(Module, on_delete=models.CASCADE)

  @property
   def subject(self):
        return self.module.subject

   def topic(self):
        return self.module.topic   

   def __str__(self):
     return self.module.topic + ' on ' + self.session_dt

   class Meta:
        db_table = 'sessions' 

我的 forms.py 是

class SessionForm(forms.ModelForm):

    class Meta:
        model = Session      
        fields = ['subject', 'topic', 'session_dt', 'grade_level', 'num_students']

我是 Django 和 Python 的新手。我已经在下拉列表中查看了 Vitor Freitas 的文章。

标签: djangoforeign-keysdropdown

解决方案


一种方法是覆盖 ModelForm 类的 init 方法并将所需字段附加到表单字段,例如:



class SessionForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(SessionForm, self).__init__(*args, **kwargs)
        self.fields['subject'].queryset = Subject.objects.all()
        self.fields['topic'].queryset = Module.objects.none()

        if 'subject' in self.data: # This will be checked when you are saving the form via a POST method
            try:
                subject_id = int(self.data.get('subject'))
                self.fields['topic'].queryset = Module.objects.filter(subject_id=subject_id)
            except:
                # catch your errors here if the form contains invalid data
        elif self.instance.pk:
            self.fields['topic'].queryset = self.instance.subject.module_set


    class Meta:
        model = Session      
        fields = ['subject', 'topic', 'session_dt', 'grade_level', 'num_students']


我认为在您的情况下,将 theSubject作为外键Session更有意义Session-> Subject-> Module
此外,当表单上主题的下拉值发生变化时,您必须进行 AJAX 调用。因此,创建一个单独的视图函数,将其映射到 URL,然后在函数内部执行以下操作:


def load_modules(request):
    subject_id = request.GET.get('subject')
    modules = Modules.objects.get(id=subject_id)
    return render(request, `template name here`, {'modules': modules})


推荐阅读