From b41f8755df4ec32041177a4b53f822bebcc8bdc7 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Mon, 10 Apr 2023 23:32:32 +0530 Subject: [PATCH] Fixes GenericForeignKey validation (#11550) * added model validation for GenericForeignKey * added ct_field and fk_field null validation * applied suggestion --- netbox/netbox/models/__init__.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/netbox/netbox/models/__init__.py b/netbox/netbox/models/__init__.py index a4c8e0ec2..96567bc55 100644 --- a/netbox/netbox/models/__init__.py +++ b/netbox/netbox/models/__init__.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.contrib.contenttypes.fields import GenericForeignKey from django.core.validators import ValidationError from django.db import models from mptt.models import MPTTModel, TreeForeignKey @@ -58,6 +59,33 @@ class NetBoxModel(CloningMixin, NetBoxFeatureSet, models.Model): class Meta: abstract = True + def clean(self): + """ + Validate the model for GenericForeignKey fields to ensure that the content type and object ID exist. + """ + super().clean() + + for field in self._meta.get_fields(): + if isinstance(field, GenericForeignKey): + ct_field = getattr(self, field.ct_field) + fk_field = getattr(self, field.fk_field) + + if ct_field is None and fk_field is not None: + raise ValidationError({ + field.ct_field: "This field cannot be null.", + }) + if fk_field is None and ct_field is not None: + raise ValidationError({ + field.fk_field: "This field cannot be null.", + }) + + if ct_field and fk_field: + klass = getattr(self, field.ct_field).model_class() + if not klass.objects.filter(pk=fk_field).exists(): + raise ValidationError({ + field.fk_field: f"Invalid {fk_field}: object does not exist on {ct_field}." + }) + class PrimaryModel(NetBoxModel): """