是的,这是一项任务,是的,我花了一些时间在上面,现在我需要帮助。
我的任务有两个模型Server
和Client
,它们处于1-N关系。如下所述
# models.py
class Server(models.Model):
name = models.CharField(max_length=255, unique=True, null=False, blank=False)
maximum_clients = models.IntegerField(default=1,null=False, blank=False)
class Client(models.Model):
name = models.CharField(max_length=255, unique=True, null=False, blank=False)
active = models.BooleanField(default=True)
server = models.ForeignKey(Server)
我已经使用ModelForm创建了一个表单,允许我在给定服务器上创建一个新客户端,但该任务的先决条件是仅提供具有可用容量的服务器(他们的maximum_clients
小于实际客户端)所以这就是我做的事情
#forms.py
from django.db.models import Count
qs = Server.objects.annotate(Count('client'))
server_choices = []
for server in qs:
if server.client__count < server.maximum_clients:
server_choices.append((server,server))
class ClientForm(forms.ModelForm):
name = forms.CharField(label='Client name')
server = forms.ChoiceField(choices=server_choices)
class Meta:
model = Client
fields = ('name','server',)
此方法根据我提到的前提条件,使用正确的服务器填充select
。但是,保存此表单会产生错误,例如Cannot assign "u'fifty'": "Client.server" must be a "Server" instance.
Fifty
是具有maximum_clients = 50
在admin
屏幕上有一个类似的表单,我也修改过它以仅显示可用的服务器并保存它们会产生相同的错误。
答案 0 :(得分:2)
这不是正确的做法。除了您看到的错误之外,您还会发现您的server_choices仅在您重新启动Web服务器时更新,而不是在服务器对象本身发生更改时更新。
您有一个外键,需要从相关对象的子集中进行选择。正确的字段是ModelChoiceField;这需要一个可以在定义中过滤的查询集。由于您的过滤器取决于同一模型中的字段,因此您需要使用F
对象。
class ClientForm(forms.ModelForm):
name = forms.CharField(label='Client name')
server = forms.ModelChoiceField(
queryset=Server.objects.annotate(client_count=Count('client')).filter(client_count__lt=F('maximum_clients')
)