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.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
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]
from .utils import FeatureQuery
#
@ -18,6 +12,10 @@ def order_content_types(field):
#
class WebhookForm(forms.ModelForm):
content_types = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('webhooks')
)
payload_url = LaxURLField(
label='URL'
)
@ -26,12 +24,6 @@ class WebhookForm(forms.ModelForm):
model = Webhook
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)
class WebhookAdmin(admin.ModelAdmin):
@ -70,6 +62,10 @@ class WebhookAdmin(admin.ModelAdmin):
#
class CustomFieldForm(forms.ModelForm):
content_types = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_fields')
)
class Meta:
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)
class CustomFieldAdmin(admin.ModelAdmin):
@ -127,6 +118,10 @@ class CustomFieldAdmin(admin.ModelAdmin):
#
class CustomLinkForm(forms.ModelForm):
content_type = ContentTypeChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_links')
)
class Meta:
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>.',
}
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)
class CustomLinkAdmin(admin.ModelAdmin):
@ -176,18 +164,15 @@ class CustomLinkAdmin(admin.ModelAdmin):
#
class ExportTemplateForm(forms.ModelForm):
content_type = ContentTypeChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_links')
)
class Meta:
model = ExportTemplate
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)
class ExportTemplateAdmin(admin.ModelAdmin):

View File

@ -329,7 +329,6 @@ class VLANGroupTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
cls.form_data = {
'name': 'VLAN Group X',
'slug': 'vlan-group-x',
'site': sites[1].pk,
'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.contenttypes.models import ContentType
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
@ -126,6 +126,10 @@ class TokenAdmin(admin.ModelAdmin):
#
class ObjectPermissionForm(forms.ModelForm):
object_types = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=OBJECTPERMISSION_OBJECT_TYPES
)
can_view = forms.BooleanField(required=False)
can_add = 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
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
self.fields['groups'].queryset = self.fields['groups'].queryset.order_by('name')
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.core.validators import MinLengthValidator
from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils import timezone
@ -14,6 +13,7 @@ from django.utils import timezone
from netbox.models import BigIDModel
from utilities.querysets import RestrictedQuerySet
from utilities.utils import flatten_dict
from .constants import *
__all__ = (
@ -251,11 +251,7 @@ class ObjectPermission(BigIDModel):
)
object_types = models.ManyToManyField(
to=ContentType,
limit_choices_to=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'])
),
limit_choices_to=OBJECTPERMISSION_OBJECT_TYPES,
related_name='object_permissions'
)
groups = models.ManyToManyField(

View File

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