我在限制formset中的可选选项时遇到了问题.我有以下模型:员工,部门,项目,项目类型,成员资格和角色.员工可以在表单集中添加/删除他们为给定部门项目播放的角色,表单应该将可选项目限制为仅属于员工所属部门的项目.
楷模:
class Department(models.Model): name = models.CharField(max_length=20) def __unicode__(self): return self.name class Employee(models.Model): fname = models.CharField(max_length=15) department = models.ForeignKey(Department) def __unicode__(self): return self.fname class Projecttype(models.Model): name = models.CharField(max_length=20) def __unicode__(self): return self.name class Project(models.Model): projecttype = models.ForeignKey(Projecttype) department = models.ForeignKey(Department) members = models.ManyToManyField(Employee,through='Membership') def __unicode__(self): return "%s > %s" % (self.department,self.projecttype) class Role(models.Model): name = models.CharField(max_length=20) def __unicode__(self): return self.name class Membership(models.Model): project = models.ForeignKey(Project,null=True) department = models.ForeignKey(Department) employee = models.ForeignKey(Employee) role = models.ManyToManyField(Role,blank=True,null=True) class Meta: unique_together = (("project","employee",),)
视图:
def employee_edit(request,employee_id): i = get_object_or_404(Employee,pk=employee_id) MembershipFormSet = modelformset_factory(Membership,exclude=('department','employee'),) f = MembershipFormSet(queryset=Membership.objects.filter(employee=i),) return render_to_response('gcs/edit.html',{'item': i,'formset': f,},context_instance=RequestContext(request))
现在,欧盟可以为任何部门项目选择一个角色.它的行为如下:
项目选择:
Projects.objects.all()
我想用这样的方式限制项目:LIMIT PROJECT CHOCIES TO:
Projects.objects.filter(department=i.department)
解决方法
这个
Stack Overflow question非常相似.我喜欢Matthew的答案,你可以在一个通过闭包访问员工的函数中动态构建表单.在你的情况下,你想要的东西:
from django.http import HttpResponseRedirect def make_membership_form(employee): """ Returns a Membership form for the given employee,restricting the Project choices to those in the employee's department. """ class MembershipForm(forms.ModelForm): project = forms.ModelChoiceField(queryset=Projects.objects.filter(department=employee.department)) class Meta: model = Membership excludes = ('department','employee',) return MembershipForm def employee_edit(request,employee_id): employee = get_object_or_404(Employee,pk=employee_id) # generate a membership form for the given employee MembershipForm = make_membership_form(employee) MembershipFormSet = modelformset_factory(Membership,form=MembershipForm) if request.method == "POST": formset = MembershipFormSet(request.POST,queryset=Membership.objects.filter(employee=employee)) if formset.is_valid(): instances = formset.save(commit=False) for member in instances: member.employee = employee member.department = employee.department member.save() formset.save_m2m() # redirect after successful update return HttpResponseRedirect("") else: formset = MembershipFormSet(queryset=Membership.objects.filter(employee=employee),) return render_to_response('testdb/edit.html',{'item': employee,'formset': formset,context_instance=RequestContext(request))