1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

#4711: Rename CustomField.obj_type to content_types

This commit is contained in:
Jeremy Stretch
2020-10-14 15:23:23 -04:00
parent defade84e4
commit 143f3cc27c
12 changed files with 37 additions and 32 deletions

View File

@ -79,7 +79,7 @@ class CustomFieldForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
order_content_types(self.fields['obj_type']) order_content_types(self.fields['content_types'])
def clean(self): def clean(self):
@ -98,7 +98,7 @@ class CustomFieldAdmin(admin.ModelAdmin):
'name', 'models', 'type', 'required', 'filter_logic', 'default', 'weight', 'description', 'name', 'models', 'type', 'required', 'filter_logic', 'default', 'weight', 'description',
] ]
list_filter = [ list_filter = [
'type', 'required', 'obj_type', 'type', 'required', 'content_types',
] ]
fieldsets = ( fieldsets = (
('Custom Field', { ('Custom Field', {
@ -106,7 +106,7 @@ class CustomFieldAdmin(admin.ModelAdmin):
}), }),
('Assignment', { ('Assignment', {
'description': 'A custom field must be assigned to one or more object types.', 'description': 'A custom field must be assigned to one or more object types.',
'fields': ('obj_type',) 'fields': ('content_types',)
}), }),
('Choices', { ('Choices', {
'description': 'A selection field must have two or more choices assigned to it.', 'description': 'A selection field must have two or more choices assigned to it.',
@ -115,7 +115,7 @@ class CustomFieldAdmin(admin.ModelAdmin):
) )
def models(self, obj): def models(self, obj):
return ', '.join([ct.name for ct in obj.obj_type.all()]) return ', '.join([ct.name for ct in obj.content_types.all()])
# #

View File

@ -24,7 +24,7 @@ class CustomFieldDefaultValues:
# Retrieve the CustomFields for the parent model # Retrieve the CustomFields for the parent model
content_type = ContentType.objects.get_for_model(self.model) content_type = ContentType.objects.get_for_model(self.model)
fields = CustomField.objects.filter(obj_type=content_type) fields = CustomField.objects.filter(content_types=content_type)
# Populate the default value for each CustomField # Populate the default value for each CustomField
value = {} value = {}
@ -52,7 +52,7 @@ class CustomFieldsDataField(Field):
""" """
if not hasattr(self, '_custom_fields'): if not hasattr(self, '_custom_fields'):
content_type = ContentType.objects.get_for_model(self.parent.Meta.model) content_type = ContentType.objects.get_for_model(self.parent.Meta.model)
self._custom_fields = CustomField.objects.filter(obj_type=content_type) self._custom_fields = CustomField.objects.filter(content_types=content_type)
return self._custom_fields return self._custom_fields
def to_representation(self, obj): def to_representation(self, obj):
@ -132,7 +132,7 @@ class CustomFieldModelSerializer(ValidatedModelSerializer):
# Retrieve the set of CustomFields which apply to this type of object # Retrieve the set of CustomFields which apply to this type of object
content_type = ContentType.objects.get_for_model(self.Meta.model) content_type = ContentType.objects.get_for_model(self.Meta.model)
fields = CustomField.objects.filter(obj_type=content_type) fields = CustomField.objects.filter(content_types=content_type)
# Populate CustomFieldValues for each instance from database # Populate CustomFieldValues for each instance from database
if type(self.instance) in (list, tuple): if type(self.instance) in (list, tuple):

View File

@ -65,9 +65,8 @@ class CustomFieldFilterSet(django_filters.FilterSet):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
obj_type = ContentType.objects.get_for_model(self._meta.model)
custom_fields = CustomField.objects.filter( custom_fields = CustomField.objects.filter(
obj_type=obj_type content_types=ContentType.objects.get_for_model(self._meta.model)
).exclude( ).exclude(
filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED
) )

View File

@ -35,7 +35,7 @@ class CustomFieldModelForm(forms.ModelForm):
Append form fields for all CustomFields assigned to this model. Append form fields for all CustomFields assigned to this model.
""" """
# Append form fields; assign initial values if modifying and existing object # Append form fields; assign initial values if modifying and existing object
for cf in CustomField.objects.filter(obj_type=self.obj_type): for cf in CustomField.objects.filter(content_types=self.obj_type):
field_name = 'cf_{}'.format(cf.name) field_name = 'cf_{}'.format(cf.name)
if self.instance.pk: if self.instance.pk:
self.fields[field_name] = cf.to_form_field(set_initial=False) self.fields[field_name] = cf.to_form_field(set_initial=False)
@ -60,7 +60,7 @@ class CustomFieldModelCSVForm(CSVModelForm, CustomFieldModelForm):
def _append_customfield_fields(self): def _append_customfield_fields(self):
# Append form fields # Append form fields
for cf in CustomField.objects.filter(obj_type=self.obj_type): for cf in CustomField.objects.filter(content_types=self.obj_type):
field_name = 'cf_{}'.format(cf.name) field_name = 'cf_{}'.format(cf.name)
self.fields[field_name] = cf.to_form_field(for_csv_import=True) self.fields[field_name] = cf.to_form_field(for_csv_import=True)
@ -77,7 +77,7 @@ class CustomFieldBulkEditForm(BulkEditForm):
self.obj_type = ContentType.objects.get_for_model(self.model) self.obj_type = ContentType.objects.get_for_model(self.model)
# Add all applicable CustomFields to the form # Add all applicable CustomFields to the form
custom_fields = CustomField.objects.filter(obj_type=self.obj_type) custom_fields = CustomField.objects.filter(content_types=self.obj_type)
for cf in custom_fields: for cf in custom_fields:
# Annotate non-required custom fields as nullable # Annotate non-required custom fields as nullable
if not cf.required: if not cf.required:
@ -96,7 +96,7 @@ class CustomFieldFilterForm(forms.Form):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# Add all applicable CustomFields to the form # Add all applicable CustomFields to the form
custom_fields = CustomField.objects.filter(obj_type=self.obj_type).exclude( custom_fields = CustomField.objects.filter(content_types=self.obj_type).exclude(
filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED
) )
for cf in custom_fields: for cf in custom_fields:

View File

@ -32,4 +32,10 @@ class Migration(migrations.Migration):
size=None size=None
), ),
), ),
# Rename obj_type to content_types
migrations.RenameField(
model_name='customfield',
old_name='obj_type',
new_name='content_types',
),
] ]

View File

@ -56,7 +56,7 @@ class Migration(migrations.Migration):
dependencies = [ dependencies = [
('circuits', '0020_custom_field_data'), ('circuits', '0020_custom_field_data'),
('dcim', '0117_custom_field_data'), ('dcim', '0117_custom_field_data'),
('extras', '0050_customfield_add_choices'), ('extras', '0050_customfield_changes'),
('ipam', '0038_custom_field_data'), ('ipam', '0038_custom_field_data'),
('secrets', '0010_custom_field_data'), ('secrets', '0010_custom_field_data'),
('tenancy', '0010_custom_field_data'), ('tenancy', '0010_custom_field_data'),

View File

@ -50,11 +50,11 @@ class CustomFieldManager(models.Manager):
Return all CustomFields assigned to the given model. Return all CustomFields assigned to the given model.
""" """
content_type = ContentType.objects.get_for_model(model._meta.concrete_model) content_type = ContentType.objects.get_for_model(model._meta.concrete_model)
return self.get_queryset().filter(obj_type=content_type) return self.get_queryset().filter(content_types=content_type)
class CustomField(models.Model): class CustomField(models.Model):
obj_type = models.ManyToManyField( content_types = models.ManyToManyField(
to=ContentType, to=ContentType,
related_name='custom_fields', related_name='custom_fields',
verbose_name='Object(s)', verbose_name='Object(s)',

View File

@ -8,7 +8,6 @@ from django.contrib.contenttypes.models import ContentType
from django.core.validators import ValidationError from django.core.validators import ValidationError
from django.db import models from django.db import models
from django.http import HttpResponse from django.http import HttpResponse
from django.template import Template, Context
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from rest_framework.utils.encoders import JSONEncoder from rest_framework.utils.encoders import JSONEncoder
@ -32,6 +31,7 @@ class Webhook(models.Model):
delete in NetBox. The request will contain a representation of the object, which the remote application can act on. delete in NetBox. The request will contain a representation of the object, which the remote application can act on.
Each Webhook can be limited to firing only on certain actions or certain object types. Each Webhook can be limited to firing only on certain actions or certain object types.
""" """
# TODO: Rename obj_type to content_types (see #4711)
obj_type = models.ManyToManyField( obj_type = models.ManyToManyField(
to=ContentType, to=ContentType,
related_name='webhooks', related_name='webhooks',

View File

@ -89,10 +89,10 @@ def handle_cf_deleted(instance, **kwargs):
""" """
Handle the cleanup of old custom field data when a CustomField is deleted. Handle the cleanup of old custom field data when a CustomField is deleted.
""" """
instance.remove_stale_data(instance.obj_type.all()) instance.remove_stale_data(instance.content_types.all())
m2m_changed.connect(handle_cf_removed_obj_types, sender=CustomField.obj_type.through) m2m_changed.connect(handle_cf_removed_obj_types, sender=CustomField.content_types.through)
pre_delete.connect(handle_cf_deleted, sender=CustomField) pre_delete.connect(handle_cf_deleted, sender=CustomField)

View File

@ -25,7 +25,7 @@ class ChangeLogViewTest(ModelViewTestCase):
required=False required=False
) )
cf.save() cf.save()
cf.obj_type.set([ct]) cf.content_types.set([ct])
def test_create_object(self): def test_create_object(self):
tags = self.create_tags('Tag 1', 'Tag 2') tags = self.create_tags('Tag 1', 'Tag 2')
@ -131,7 +131,7 @@ class ChangeLogAPITest(APITestCase):
required=False required=False
) )
cf.save() cf.save()
cf.obj_type.set([ct]) cf.content_types.set([ct])
# Create some tags # Create some tags
tags = ( tags = (

View File

@ -39,7 +39,7 @@ class CustomFieldTest(TestCase):
# Create a custom field # Create a custom field
cf = CustomField(type=data['field_type'], name='my_field', required=False) cf = CustomField(type=data['field_type'], name='my_field', required=False)
cf.save() cf.save()
cf.obj_type.set([obj_type]) cf.content_types.set([obj_type])
cf.save() cf.save()
# Assign a value to the first Site # Assign a value to the first Site
@ -72,7 +72,7 @@ class CustomFieldTest(TestCase):
choices=['Option A', 'Option B', 'Option C'] choices=['Option A', 'Option B', 'Option C']
) )
cf.save() cf.save()
cf.obj_type.set([obj_type]) cf.content_types.set([obj_type])
cf.save() cf.save()
# Assign a value to the first Site # Assign a value to the first Site
@ -100,7 +100,7 @@ class CustomFieldManagerTest(TestCase):
content_type = ContentType.objects.get_for_model(Site) content_type = ContentType.objects.get_for_model(Site)
custom_field = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='text_field', default='foo') custom_field = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='text_field', default='foo')
custom_field.save() custom_field.save()
custom_field.obj_type.set([content_type]) custom_field.content_types.set([content_type])
def test_get_for_model(self): def test_get_for_model(self):
self.assertEqual(CustomField.objects.get_for_model(Site).count(), 1) self.assertEqual(CustomField.objects.get_for_model(Site).count(), 1)
@ -116,33 +116,33 @@ class CustomFieldAPITest(APITestCase):
# Text custom field # Text custom field
cls.cf_text = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='text_field', default='foo') cls.cf_text = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='text_field', default='foo')
cls.cf_text.save() cls.cf_text.save()
cls.cf_text.obj_type.set([content_type]) cls.cf_text.content_types.set([content_type])
# Integer custom field # Integer custom field
cls.cf_integer = CustomField(type=CustomFieldTypeChoices.TYPE_INTEGER, name='number_field', default=123) cls.cf_integer = CustomField(type=CustomFieldTypeChoices.TYPE_INTEGER, name='number_field', default=123)
cls.cf_integer.save() cls.cf_integer.save()
cls.cf_integer.obj_type.set([content_type]) cls.cf_integer.content_types.set([content_type])
# Boolean custom field # Boolean custom field
cls.cf_boolean = CustomField(type=CustomFieldTypeChoices.TYPE_BOOLEAN, name='boolean_field', default=False) cls.cf_boolean = CustomField(type=CustomFieldTypeChoices.TYPE_BOOLEAN, name='boolean_field', default=False)
cls.cf_boolean.save() cls.cf_boolean.save()
cls.cf_boolean.obj_type.set([content_type]) cls.cf_boolean.content_types.set([content_type])
# Date custom field # Date custom field
cls.cf_date = CustomField(type=CustomFieldTypeChoices.TYPE_DATE, name='date_field', default='2020-01-01') cls.cf_date = CustomField(type=CustomFieldTypeChoices.TYPE_DATE, name='date_field', default='2020-01-01')
cls.cf_date.save() cls.cf_date.save()
cls.cf_date.obj_type.set([content_type]) cls.cf_date.content_types.set([content_type])
# URL custom field # URL custom field
cls.cf_url = CustomField(type=CustomFieldTypeChoices.TYPE_URL, name='url_field', default='http://example.com/1') cls.cf_url = CustomField(type=CustomFieldTypeChoices.TYPE_URL, name='url_field', default='http://example.com/1')
cls.cf_url.save() cls.cf_url.save()
cls.cf_url.obj_type.set([content_type]) cls.cf_url.content_types.set([content_type])
# Select custom field # Select custom field
cls.cf_select = CustomField(type=CustomFieldTypeChoices.TYPE_SELECT, name='choice_field', choices=['Foo', 'Bar', 'Baz']) cls.cf_select = CustomField(type=CustomFieldTypeChoices.TYPE_SELECT, name='choice_field', choices=['Foo', 'Bar', 'Baz'])
cls.cf_select.default = 'Foo' cls.cf_select.default = 'Foo'
cls.cf_select.save() cls.cf_select.save()
cls.cf_select.obj_type.set([content_type]) cls.cf_select.content_types.set([content_type])
# Create some sites # Create some sites
cls.sites = ( cls.sites = (
@ -429,7 +429,7 @@ class CustomFieldImportTest(TestCase):
) )
for cf in custom_fields: for cf in custom_fields:
cf.save() cf.save()
cf.obj_type.set([ContentType.objects.get_for_model(Site)]) cf.content_types.set([ContentType.objects.get_for_model(Site)])
def test_import(self): def test_import(self):
""" """

View File

@ -131,7 +131,7 @@ class APIDocsTestCase(TestCase):
content_type = ContentType.objects.get_for_model(Site) content_type = ContentType.objects.get_for_model(Site)
self.cf_text = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='test') self.cf_text = CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='test')
self.cf_text.save() self.cf_text.save()
self.cf_text.obj_type.set([content_type]) self.cf_text.content_types.set([content_type])
self.cf_text.save() self.cf_text.save()
def test_api_docs(self): def test_api_docs(self):