Use ContentTypeChoiceField for all ContentType fields

This commit is contained in:
Jeremy Stretch 2021-04-02 10:55:16 -04:00
parent 73e9842877
commit d82f2e289a
6 changed files with 45 additions and 48 deletions

View File

@ -1,16 +1,10 @@
from django import forms from django import forms
from django.contrib import admin from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from utilities.forms import LaxURLField from utilities.forms import ContentTypeChoiceField, ContentTypeMultipleChoiceField, LaxURLField
from .models import CustomField, CustomLink, ExportTemplate, JobResult, Webhook from .models import CustomField, CustomLink, ExportTemplate, JobResult, Webhook
from .utils import FeatureQuery
def order_content_types(field):
"""
Order the list of available ContentTypes by application
"""
queryset = field.queryset.order_by('app_label', 'model')
field.choices = [(ct.pk, '{} > {}'.format(ct.app_label, ct.name)) for ct in queryset]
# #
@ -18,6 +12,10 @@ def order_content_types(field):
# #
class WebhookForm(forms.ModelForm): class WebhookForm(forms.ModelForm):
content_types = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('webhooks')
)
payload_url = LaxURLField( payload_url = LaxURLField(
label='URL' label='URL'
) )
@ -26,12 +24,6 @@ class WebhookForm(forms.ModelForm):
model = Webhook model = Webhook
exclude = () exclude = ()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'content_types' in self.fields:
order_content_types(self.fields['content_types'])
@admin.register(Webhook) @admin.register(Webhook)
class WebhookAdmin(admin.ModelAdmin): class WebhookAdmin(admin.ModelAdmin):
@ -70,6 +62,10 @@ class WebhookAdmin(admin.ModelAdmin):
# #
class CustomFieldForm(forms.ModelForm): class CustomFieldForm(forms.ModelForm):
content_types = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_fields')
)
class Meta: class Meta:
model = CustomField model = CustomField
@ -84,11 +80,6 @@ class CustomFieldForm(forms.ModelForm):
) )
} }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
order_content_types(self.fields['content_types'])
@admin.register(CustomField) @admin.register(CustomField)
class CustomFieldAdmin(admin.ModelAdmin): class CustomFieldAdmin(admin.ModelAdmin):
@ -127,6 +118,10 @@ class CustomFieldAdmin(admin.ModelAdmin):
# #
class CustomLinkForm(forms.ModelForm): class CustomLinkForm(forms.ModelForm):
content_type = ContentTypeChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_links')
)
class Meta: class Meta:
model = CustomLink model = CustomLink
@ -143,13 +138,6 @@ class CustomLinkForm(forms.ModelForm):
'link_url': 'Jinja2 template code for the link URL. Reference the object as <code>{{ obj }}</code>.', 'link_url': 'Jinja2 template code for the link URL. Reference the object as <code>{{ obj }}</code>.',
} }
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Format ContentType choices
order_content_types(self.fields['content_type'])
self.fields['content_type'].choices.insert(0, ('', '---------'))
@admin.register(CustomLink) @admin.register(CustomLink)
class CustomLinkAdmin(admin.ModelAdmin): class CustomLinkAdmin(admin.ModelAdmin):
@ -176,18 +164,15 @@ class CustomLinkAdmin(admin.ModelAdmin):
# #
class ExportTemplateForm(forms.ModelForm): class ExportTemplateForm(forms.ModelForm):
content_type = ContentTypeChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_links')
)
class Meta: class Meta:
model = ExportTemplate model = ExportTemplate
exclude = [] exclude = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Format ContentType choices
order_content_types(self.fields['content_type'])
self.fields['content_type'].choices.insert(0, ('', '---------'))
@admin.register(ExportTemplate) @admin.register(ExportTemplate)
class ExportTemplateAdmin(admin.ModelAdmin): class ExportTemplateAdmin(admin.ModelAdmin):

View File

@ -329,7 +329,6 @@ class VLANGroupTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
cls.form_data = { cls.form_data = {
'name': 'VLAN Group X', 'name': 'VLAN Group X',
'slug': 'vlan-group-x', 'slug': 'vlan-group-x',
'site': sites[1].pk,
'description': 'A new VLAN group', 'description': 'A new VLAN group',
} }

View File

@ -4,9 +4,9 @@ from django.contrib.auth.admin import UserAdmin as UserAdmin_
from django.contrib.auth.models import Group, User from django.contrib.auth.models import Group, User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import FieldError, ValidationError from django.core.exceptions import FieldError, ValidationError
from django.db.models import Q
from extras.admin import order_content_types from utilities.forms.fields import ContentTypeMultipleChoiceField
from .constants import *
from .models import AdminGroup, AdminUser, ObjectPermission, Token, UserConfig from .models import AdminGroup, AdminUser, ObjectPermission, Token, UserConfig
@ -126,6 +126,10 @@ class TokenAdmin(admin.ModelAdmin):
# #
class ObjectPermissionForm(forms.ModelForm): class ObjectPermissionForm(forms.ModelForm):
object_types = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=OBJECTPERMISSION_OBJECT_TYPES
)
can_view = forms.BooleanField(required=False) can_view = forms.BooleanField(required=False)
can_add = forms.BooleanField(required=False) can_add = forms.BooleanField(required=False)
can_change = forms.BooleanField(required=False) can_change = forms.BooleanField(required=False)
@ -153,10 +157,6 @@ class ObjectPermissionForm(forms.ModelForm):
# Make the actions field optional since the admin form uses it only for non-CRUD actions # Make the actions field optional since the admin form uses it only for non-CRUD actions
self.fields['actions'].required = False self.fields['actions'].required = False
# Format ContentType choices
order_content_types(self.fields['object_types'])
self.fields['object_types'].choices.insert(0, ('', '---------'))
# Order group and user fields # Order group and user fields
self.fields['groups'].queryset = self.fields['groups'].queryset.order_by('name') self.fields['groups'].queryset = self.fields['groups'].queryset.order_by('name')
self.fields['users'].queryset = self.fields['users'].queryset.order_by('username') self.fields['users'].queryset = self.fields['users'].queryset.order_by('username')

View File

@ -0,0 +1,8 @@
from django.db.models import Q
OBJECTPERMISSION_OBJECT_TYPES = Q(
~Q(app_label__in=['admin', 'auth', 'contenttypes', 'sessions', 'taggit', 'users']) |
Q(app_label='auth', model__in=['group', 'user']) |
Q(app_label='users', model__in=['objectpermission', 'token'])
)

View File

@ -6,7 +6,6 @@ from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.core.validators import MinLengthValidator from django.core.validators import MinLengthValidator
from django.db import models from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import timezone from django.utils import timezone
@ -14,6 +13,7 @@ from django.utils import timezone
from netbox.models import BigIDModel from netbox.models import BigIDModel
from utilities.querysets import RestrictedQuerySet from utilities.querysets import RestrictedQuerySet
from utilities.utils import flatten_dict from utilities.utils import flatten_dict
from .constants import *
__all__ = ( __all__ = (
@ -251,11 +251,7 @@ class ObjectPermission(BigIDModel):
) )
object_types = models.ManyToManyField( object_types = models.ManyToManyField(
to=ContentType, to=ContentType,
limit_choices_to=Q( limit_choices_to=OBJECTPERMISSION_OBJECT_TYPES,
~Q(app_label__in=['admin', 'auth', 'contenttypes', 'sessions', 'taggit', 'users']) |
Q(app_label='auth', model__in=['group', 'user']) |
Q(app_label='users', model__in=['objectpermission', 'token'])
),
related_name='object_permissions' related_name='object_permissions'
) )
groups = models.ManyToManyField( groups = models.ManyToManyField(

View File

@ -21,6 +21,7 @@ from .utils import expand_alphanumeric_pattern, expand_ipaddress_pattern
__all__ = ( __all__ = (
'CommentField', 'CommentField',
'ContentTypeChoiceField', 'ContentTypeChoiceField',
'ContentTypeMultipleChoiceField',
'CSVChoiceField', 'CSVChoiceField',
'CSVContentTypeField', 'CSVContentTypeField',
'CSVDataField', 'CSVDataField',
@ -114,7 +115,7 @@ class JSONField(_JSONField):
return json.dumps(value, sort_keys=True, indent=4) return json.dumps(value, sort_keys=True, indent=4)
class ContentTypeChoiceField(forms.ModelChoiceField): class ContentTypeChoiceMixin:
def __init__(self, queryset, *args, **kwargs): def __init__(self, queryset, *args, **kwargs):
# Order ContentTypes by app_label # Order ContentTypes by app_label
@ -126,6 +127,14 @@ class ContentTypeChoiceField(forms.ModelChoiceField):
return f'{meta.app_config.verbose_name} > {meta.verbose_name}' return f'{meta.app_config.verbose_name} > {meta.verbose_name}'
class ContentTypeChoiceField(ContentTypeChoiceMixin, forms.ModelChoiceField):
pass
class ContentTypeMultipleChoiceField(ContentTypeChoiceMixin, forms.ModelMultipleChoiceField):
pass
# #
# CSV fields # CSV fields
# #