我有3种型号:
class Node(models.Model):
ID = models.DecimalField(max_digits=19, decimal_places=10)
name = models.CharField(default='node', max_length=32)
connexion = models.CharField(max_length=255)
# Many2one fields | Foreign keys:
firm = models.ForeignKey('firme.Firme', on_delete=models.CASCADE, null=True, blank=True)
class ScheduledAction(models.Model):
date = models.DateTimeField(default=datetime.now, blank=True)
firm = models.ForeignKey('firme.Firme', on_delete=models.CASCADE, null=True, blank=True)
node_ids = models.ManyToManyField(Node)
我希望在ScheduledAction表单中为选定的公司显示其相关节点的列表。通常我应该通过get
来做到这一点:
class ScheduledActionForm(forms.ModelForm):
date = forms.DateTimeField()
firm = forms.ModelChoiceField(queryset=Firme.objects.all())
node_ids = forms.ModelMultipleChoiceField(queryset=Node.objects.get(firm_id=firm.id), widget=forms.CheckboxSelectMultiple)
class Meta:
model = ScheduledAction
fields = [
'date',
'firm',
'node_ids'
]
这是我的views.py:
def planification_view(request, id):
scheduledAction = ScheduledActionForm(request.POST or None)
firme = get_object_or_404(Firme, id=id)
nodes = Node.objects.all()
if scheduledAction.is_valid():
scheduledAction.save()
print('formulaire enregistre')
scheduledAction = ScheduledActionForm()
context = {
'firme': firme,
'form': scheduledAction,
'nodes': nodes
}
return render(request, "node/planification.html", context)
但是我得到了这个错误:
AttributeError: 'ModelChoiceField' object has no attribute 'id'
我该如何解决?
答案 0 :(得分:2)
您的方法有几处错误
首先:您将变量'firm'分配给表单字段,然后使用该变量从数据库获取对象无论如何都行不通。 Node.objects.get(firm_id=firm.id)
中的变量'firm'应该是一个牢固的实例。
秒:queryset=Node.objects.get(firm_id=firm.id)
将不起作用,因为Model.objects.get()将返回对象而不是查询集。
如果要显示特定公司的所有节点,则需要将公司对象(或ID或其他标识符)传递给表单,例如,如果使用的是CBV,则将其通过get_form_kwargs()
传递给表单并对其进行过滤Node.objects.filter(firm_id=firm.id)
更新: 由于您使用的是基于函数的视图,因此可能会有更干燥的方法,但是我只习惯使用CBV,所以我会尽力而为
在表单上,我们将声明一个名为firme的新变量(将其传递给您视图中的表单)
class ScheduledActionForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.firme = kwargs.pop('firme')
super(ScheduledActionForm, self).__init__(*args, **kwargs)
self.fields['node_ids'].queryset = Node.objects.filter(firm_id=self.firme.id)
date = forms.DateTimeField()
firm = forms.ModelChoiceField(queryset=Firme.objects.all()) # why do you want a list of all firms here? Or do you want a single object?
node_ids = forms.ModelMultipleChoiceField(queryset=Node.objects.none()), widget=forms.CheckboxSelectMultiple)
class Meta:
model = ScheduledAction
fields = [
'date',
'firm',
'node_ids'
]
现在为您查看:
def planification_view(request, id):
firme = get_object_or_404(Firme, id=id)
nodes = Node.objects.all()
if request.method == 'POST':
form = ScheduledActionForm(data=request.POST, firme=firme)
if form.is_valid():
scheduledAction = form.save()
print('formulaire enregistre')
else:
form = ScheduledActionForm(firme=firme)
context = {
'firme': firme,
'form': form,
'nodes': nodes
}
return render(request, "node/planification.html", context)
遵循这些思路应该可以助您一臂之力。可能仍需要进行一些调整才能使其在您的项目中正常工作。如果您仍然无法理解,请阅读Django docs或阅读其教程
更新2: 不是最漂亮的解决方案,但它适用于OP