2009-12-24 65 views
0

我有一个相当复杂的关系,我试图使用Django管理站点进行工作。我花了相当一段时间来试图解决这个问题,看起来好像我没有得到Django模型背后的哲学。Django:构建与内置管理站点配合使用的复杂关系

有一个组的列表。每个小组都有多个部门。也有员工。每个员工属于一个组,但某些员工也属于一个组内的一个部门。 (有些员工可能只属于一个集团,但不属于部门,但没有员工只属于一个部门)。

这里是什么,我现在有一个简化版本:

class Group: 
    name = models.CharField(max_length=128) 

class Department 
    group = models.ForeignKey(Group) 

class Employee 
    department = models.ForeignKey(Department) 
    group = models.ForeignKey(Group) 

这样做的问题是,员工页面上的部门选择框必须显示所有的部门,因为一组尚未设定。我试图通过为GroupAdmin页面创建一个EmployeeInline来纠正这种情况,但在非分页内联中拥有500多名员工并不好。我必须能够为Employees员工使用models.ModelAdmin页面(除非有内联搜索,排序,折叠和执行操作的方法)。

如果我让EmployeeInline DepartmentAdmin的内联(而不必在GroupAdmin一个DepartmentInline),那么事情更糟,因为它是不可能有不属于一个集团的员工。

鉴于我对关系的描述,我是否错过了Django ORM的某些部分,这将允许我按照“应该”的方式构建这种关系,而不是剽窃并试图让事情走到一起?

非常感谢。

回答

3

这听起来像你想要的部门选项只是那些ForeignKey'ed到组?标准答案是管理网站仅适用于简单的CRUD操作。

但是做你应该做的事是无聊的。

你可以用一些忍者javascript和JSON来克服这个限制。

所以首先,我们需要一个API,让我们知道哪些部门可用于每个组。

def api_departments_from_group(request, group_id): 
    departments = Department.objects.filter(group__id=group_id) 
    return json(departments) # Note: serialize, however 

一旦API是在地方,我们可以添加一些JavaScript来改变对部门<option>的选择...

$(function() { 
    // On page load... 
    if ($('#id_group')) { 
     // Trap when the group box is changed 
     $('#id_group').bind('blur', function() { 
      $.getJSON('/api/get-departments/' + $('#id_group').val() + '/', function(data) { 
       // Clear existing options 
       $('#id_department').children().remove(); 
       // Parse JSON and turn into <option> tags 
       $.each(data, function(i, item) { 
        $('#id_department').append('<option>' + item.name + '</option>'); 
       }); 
      }); 
     }); 
    } 
}); 

保存,要管理,ninja.js。然后,可将它的管理模式本身......

class EmployeeAdmin(models.ModelAdmin): 

    # ... 

    class Media: 
     js = ('/media/admin-ninja.js',) 

呀,所以我没有测试这种下降,但你可以希望得到一些想法。此外,我没有看到任何东西,例如javascript没有考虑已经被选中的选项(然后重新选择它)。