Correct handling of GenericForeignKey in PrefixForm

This commit is contained in:
Jeremy Stretch 2024-10-10 08:51:07 -04:00
parent 5858557040
commit d829144c75
3 changed files with 16 additions and 11 deletions

View File

@ -207,7 +207,7 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
required=False, required=False,
label=_('Scope type') label=_('Scope type')
) )
scope_id = DynamicModelChoiceField( scope = DynamicModelChoiceField(
label=_('Scope'), label=_('Scope'),
queryset=Site.objects.none(), # Initial queryset queryset=Site.objects.none(), # Initial queryset
required=False, required=False,
@ -234,7 +234,7 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
FieldSet( FieldSet(
'prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags', name=_('Prefix') 'prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags', name=_('Prefix')
), ),
FieldSet('scope_type', 'scope_id', name=_('Scope')), FieldSet('scope_type', 'scope', name=_('Scope')),
FieldSet('vlan', name=_('VLAN Assignment')), FieldSet('vlan', name=_('VLAN Assignment')),
FieldSet('tenant_group', 'tenant', name=_('Tenancy')), FieldSet('tenant_group', 'tenant', name=_('Tenancy')),
) )
@ -242,8 +242,8 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
class Meta: class Meta:
model = Prefix model = Prefix
fields = [ fields = [
'prefix', 'vrf', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'scope_type', 'scope_id', 'prefix', 'vrf', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'scope_type', 'tenant_group',
'tenant_group', 'tenant', 'description', 'comments', 'tags', 'tenant', 'description', 'comments', 'tags',
] ]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -260,21 +260,21 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
try: try:
scope_type = ContentType.objects.get(pk=scope_type_id) scope_type = ContentType.objects.get(pk=scope_type_id)
model = scope_type.model_class() model = scope_type.model_class()
self.fields['scope_id'].queryset = model.objects.all() self.fields['scope'].queryset = model.objects.all()
self.fields['scope_id'].widget.attrs['selector'] = model._meta.label_lower self.fields['scope'].widget.attrs['selector'] = model._meta.label_lower
self.fields['scope_id'].disabled = False self.fields['scope'].disabled = False
self.fields['scope_id'].label = _(bettertitle(model._meta.verbose_name)) self.fields['scope'].label = _(bettertitle(model._meta.verbose_name))
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass pass
if self.instance and scope_type_id != self.instance.scope_type_id: if self.instance and scope_type_id != self.instance.scope_type_id:
self.initial['scope_id'] = None self.initial['scope'] = None
def clean(self): def clean(self):
super().clean() super().clean()
# Assign the selected scope (if any) # Assign the selected scope (if any)
self.instance.scope = self.cleaned_data.get('scope_id') self.instance.scope = self.cleaned_data.get('scope')
class IPRangeForm(TenancyForm, NetBoxModelForm): class IPRangeForm(TenancyForm, NetBoxModelForm):

View File

@ -421,7 +421,7 @@ class PrefixTestCase(ViewTestCases.PrimaryObjectViewTestCase):
cls.form_data = { cls.form_data = {
'prefix': IPNetwork('192.0.2.0/24'), 'prefix': IPNetwork('192.0.2.0/24'),
'scope_type': ContentType.objects.get_for_model(Site).pk, 'scope_type': ContentType.objects.get_for_model(Site).pk,
'scope_id': sites[1].pk, 'scope': sites[1].pk,
'vrf': vrfs[1].pk, 'vrf': vrfs[1].pk,
'tenant': None, 'tenant': None,
'vlan': None, 'vlan': None,

View File

@ -1,5 +1,6 @@
import json import json
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import ArrayField, RangeField from django.contrib.postgres.fields import ArrayField, RangeField
from django.core.exceptions import FieldDoesNotExist from django.core.exceptions import FieldDoesNotExist
@ -120,6 +121,10 @@ class ModelTestCase(TestCase):
else: else:
model_dict[key] = sorted([obj.pk for obj in value]) model_dict[key] = sorted([obj.pk for obj in value])
# Handle GenericForeignKeys
elif value and type(field) is GenericForeignKey:
model_dict[key] = value.pk
elif api: elif api:
# Replace ContentType numeric IDs with <app_label>.<model> # Replace ContentType numeric IDs with <app_label>.<model>