在Admin中基于其他字段填充Django ManyToManyField选项

时间:2017-01-18 19:19:48

标签: python django django-models django-forms django-admin

我在Django Admin Add屏幕上根据对同一表单上另一个字段的输入过滤ManyToManyField的选项时遇到问题。我是Django的新手,并且无法使用其他地方描述的任何通用修补程序,因为它们与我的情况略有不同。这是我的情况:

我的项目中有三个模型:ClassStudentAttendanceRecord。在Django Admin中,添加出勤记录时,我想根据为字段Absent_Students所做的选择更改字段Associated_Class的选项。因此,例如,如果Associated_Class" CS 450"如果选中,Absent_Students的选项应更改为只有class_list包含CS 450的学生。

以下是我的模特:

from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User
from django.utils.encoding import python_2_unicode_compatible
import random, string

# Create your models here.

#This is the model for a student
@python_2_unicode_compatible
class Student(models.Model):
    pass
    Student_First_Name = models.CharField(max_length=200)
    Student_Last_Name = models.CharField(max_length=200)
    Student_ID_Number = models.CharField(max_length=200)
    Student_Class = models.ForeignKey('Class', null=True)
    def __str__(self):
        return self.Student_Last_Name + ',' + self.Student_First_Name

# This is the model for a class
@python_2_unicode_compatible
class Class(models.Model):  

    class Meta:
        verbose_name_plural = "Classes"
    Class_Name = models.CharField(max_length=200)
    Student_List = models.ManyToManyField('Student', related_name='class_list')
    Professor = models.ForeignKey(User,null=True)
    AddCode = models.IntegerField
    pass
    def __str__(self):
        return self.Class_Name
    def getName(self):
        return self.Class_Name
    def getProfessor(self):
        return self.Professor.id
    def getProf(self):
        return self.Professor
    def getStudents(self):
        return self.Student_List

#This is the model for attendance records
class AttendanceRecord(models.Model):
    class Meta:
        verbose_name = "Attendance Record"
    Associated_Class = models.ForeignKey(Class, on_delete=models.CASCADE, related_name='Attendance_Records')
    Date = models.DateField()
    Absent_Students = models.ManyToManyField('Student', blank=True)
    Present_Students = models.ManyToManyField('Student', related_name='a')
    def get_associated_class_id(self):
        return self.Associated_Class
    def __str__(self):
        return self.Associated_Class.__str__() + ' on date ' + self.Date.__str__(self)

我尝试过编辑AttendanceRecordAdminForm类和AttendanceRecordAdmin类。我的问题是,在设置self.fields['Absent_Students].queryset时,我不知道如何访问表单上当前选定的Associated_Class。我一直收到一个错误,#34; AttendanceRecord没有Associated_Class"。以下是刚才讨论的那些课程:

class AttendanceRecordAdminForm(forms.ModelForm):

  class Meta:
    model = AttendanceRecord
    fields = '__all__'

  def __init__(self, *args, **kwargs):
    super(AttendanceRecordAdminForm, self).__init__(*args, **kwargs)
    instance = kwargs.get('instance', None)
    self.fields['Absent_Students'].queryset = Student.objects.filter(class_list__id=self.instance.get_associated_class_id())
    self.fields['Present_Students'].queryset = Student.objects.filter(class_list__id=1)


class AttendanceRecordAdmin(admin.ModelAdmin):
  form = AttendanceRecordAdminForm
  filter_horizontal = ('Absent_Students', 'Present_Students',)

基本上,我正在寻找一种方法来访问管理表单上当前输入的Associated_Class,以便我可以正确过滤查询集。

1 个答案:

答案 0 :(得分:0)

经过几个小时的在线搜索,我终于找到了我需要的东西。来自smart_select应用程序的链式ManyToMany使这非常容易。此链接:How to use django-smart-select描述了安装过程,还链接到安装后使用它的文档。希望这对其他人也有帮助。