Reputation: 25
I have a Django application with three models:
class Strategy(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
...
class Version(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
strategy = models.ForeignKey(Strategy, on_delete=models.CASCADE)
...
class Tool(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
version = models.OneToOneField(Version, on_delete=models.CASCADE)
...
On the Tool model's corresponding ToolForm, I filter the QuerySet for the 'version' field, so that the User only sees the strategy versions they submitted:
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['version'].queryset = Version.objects.filter(strategy__user=user.id)
I now want to filter this QuerySet further to exclude Versions which already have Tools. The Version to Tool relationship is One-to-One, and I only want the User to see Versions which still require Tools to be submitted. I have tried numerous approaches, but I keep coming back to versions of:
Version.objects.filter(strategy__user=user.id).exclude(Tool.objects.filter(version__strategy__user=user.id).values('version_id'))
Version.objects.filter(strategy__user=user.id).exclude(Tool.objects.filter(version__strategy__user=user.id).values_list('version_id'))
Both "exclude" queries return the One-to-One field 'version_id' for the Tool entries. Respectively, the responses I get are:
'dict' object has no attribute 'split'
'tuple' object has no attribute 'split'
What am I missing? How can I exclude Versions from my ToolForm 'version' field that already have the One-to-One relationship established?
Upvotes: 1
Views: 83
Reputation: 51988
You do not need exclude here. You can simply use tool__isnull=True
:
Version.objects.filter(strategy__user=user.id, tool__isnull=True)
Due to OneToOne relation between Version and Tool instances, Version has a field named tool
(all lowercase model name unless you defined related_name
). For Version instances which does not have Tool, the field will be empty. So isnull=True
will check for Version instances which does not have any tool.
Upvotes: 1