django - 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 的文章。
解决方案
一种方法是覆盖 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})
推荐阅读
- azure - 可以通过 Web 应用程序防火墙状态/计费以编程方式暂停/恢复 Azure 的应用程序网关吗?
- python - python numpy linalg求解器:错误答案
- postgresql - Grafana Postgres 查询编辑器和 pg_prometheus (timescaledb)
- c# - 找不到类型或命名空间。但是有参考资料
- vue.js - 如何将 nextPage 变量值从孩子传递到父母的路由器链接?
- python - 仅使用 python regex 获取文本
- javascript - js针对内部ul的第一个li
- prolog - Prolog DCG Sytnax 错误:应为操作员
- python - 在 python opencv 中显示来自 Bag of Visual Words 的 Visual word 示例/样本
- keras - 使用 ** layers[0].get_weights()[0]** 的嵌入