from django import forms
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext as _

from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup
from extras.choices import *
from extras.models import *
from extras.utils import FeatureQuery
from netbox.forms.base import NetBoxModelFilterSetForm
from tenancy.models import Tenant, TenantGroup
from utilities.forms import (
    add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField,
    ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField,
    StaticSelect, TagFilterField,
)
from virtualization.models import Cluster, ClusterGroup, ClusterType

__all__ = (
    'ConfigContextFilterForm',
    'CustomFieldFilterForm',
    'CustomLinkFilterForm',
    'ExportTemplateFilterForm',
    'JournalEntryFilterForm',
    'LocalConfigContextFilterForm',
    'ObjectChangeFilterForm',
    'TagFilterForm',
    'WebhookFilterForm',
)


class CustomFieldFilterForm(FilterForm):
    fieldsets = (
        (None, ('q',)),
        ('Attributes', ('type', 'content_types', 'weight', 'required')),
    )
    content_types = ContentTypeMultipleChoiceField(
        queryset=ContentType.objects.all(),
        limit_choices_to=FeatureQuery('custom_fields'),
        required=False
    )
    type = MultipleChoiceField(
        choices=CustomFieldTypeChoices,
        required=False,
        label=_('Field type')
    )
    weight = forms.IntegerField(
        required=False
    )
    required = forms.NullBooleanField(
        required=False,
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )


class CustomLinkFilterForm(FilterForm):
    fieldsets = (
        (None, ('q',)),
        ('Attributes', ('content_type', 'enabled', 'new_window', 'weight')),
    )
    content_type = ContentTypeChoiceField(
        queryset=ContentType.objects.all(),
        limit_choices_to=FeatureQuery('custom_links'),
        required=False
    )
    enabled = forms.NullBooleanField(
        required=False,
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )
    new_window = forms.NullBooleanField(
        required=False,
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )
    weight = forms.IntegerField(
        required=False
    )


class ExportTemplateFilterForm(FilterForm):
    fieldsets = (
        (None, ('q',)),
        ('Attributes', ('content_type', 'mime_type', 'file_extension', 'as_attachment')),
    )
    content_type = ContentTypeChoiceField(
        queryset=ContentType.objects.all(),
        limit_choices_to=FeatureQuery('export_templates'),
        required=False
    )
    mime_type = forms.CharField(
        required=False,
        label=_('MIME type')
    )
    file_extension = forms.CharField(
        required=False
    )
    as_attachment = forms.NullBooleanField(
        required=False,
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )


class WebhookFilterForm(FilterForm):
    fieldsets = (
        (None, ('q',)),
        ('Attributes', ('content_types', 'http_method', 'enabled')),
        ('Events', ('type_create', 'type_update', 'type_delete')),
    )
    content_types = ContentTypeMultipleChoiceField(
        queryset=ContentType.objects.all(),
        limit_choices_to=FeatureQuery('webhooks'),
        required=False
    )
    http_method = MultipleChoiceField(
        choices=WebhookHttpMethodChoices,
        required=False,
        label=_('HTTP method')
    )
    enabled = forms.NullBooleanField(
        required=False,
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )
    type_create = forms.NullBooleanField(
        required=False,
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )
    type_update = forms.NullBooleanField(
        required=False,
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )
    type_delete = forms.NullBooleanField(
        required=False,
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )


class TagFilterForm(FilterForm):
    model = Tag
    content_type_id = ContentTypeMultipleChoiceField(
        queryset=ContentType.objects.filter(FeatureQuery('tags').get_query()),
        required=False,
        label=_('Tagged object type')
    )


class ConfigContextFilterForm(FilterForm):
    fieldsets = (
        (None, ('q', 'tag_id')),
        ('Location', ('region_id', 'site_group_id', 'site_id')),
        ('Device', ('device_type_id', 'platform_id', 'role_id')),
        ('Cluster', ('cluster_type_id', 'cluster_group_id', 'cluster_id')),
        ('Tenant', ('tenant_group_id', 'tenant_id'))
    )
    region_id = DynamicModelMultipleChoiceField(
        queryset=Region.objects.all(),
        required=False,
        label=_('Regions')
    )
    site_group_id = DynamicModelMultipleChoiceField(
        queryset=SiteGroup.objects.all(),
        required=False,
        label=_('Site groups')
    )
    site_id = DynamicModelMultipleChoiceField(
        queryset=Site.objects.all(),
        required=False,
        label=_('Sites')
    )
    device_type_id = DynamicModelMultipleChoiceField(
        queryset=DeviceType.objects.all(),
        required=False,
        label=_('Device types')
    )
    role_id = DynamicModelMultipleChoiceField(
        queryset=DeviceRole.objects.all(),
        required=False,
        label=_('Roles')
    )
    platform_id = DynamicModelMultipleChoiceField(
        queryset=Platform.objects.all(),
        required=False,
        label=_('Platforms')
    )
    cluster_type_id = DynamicModelMultipleChoiceField(
        queryset=ClusterType.objects.all(),
        required=False,
        label=_('Cluster types'),
        fetch_trigger='open'
    )
    cluster_group_id = DynamicModelMultipleChoiceField(
        queryset=ClusterGroup.objects.all(),
        required=False,
        label=_('Cluster groups')
    )
    cluster_id = DynamicModelMultipleChoiceField(
        queryset=Cluster.objects.all(),
        required=False,
        label=_('Clusters')
    )
    tenant_group_id = DynamicModelMultipleChoiceField(
        queryset=TenantGroup.objects.all(),
        required=False,
        label=_('Tenant groups')
    )
    tenant_id = DynamicModelMultipleChoiceField(
        queryset=Tenant.objects.all(),
        required=False,
        label=_('Tenant')
    )
    tag_id = DynamicModelMultipleChoiceField(
        queryset=Tag.objects.all(),
        required=False,
        label=_('Tags')
    )


class LocalConfigContextFilterForm(forms.Form):
    local_context_data = forms.NullBooleanField(
        required=False,
        label=_('Has local config context data'),
        widget=StaticSelect(
            choices=BOOLEAN_WITH_BLANK_CHOICES
        )
    )


class JournalEntryFilterForm(NetBoxModelFilterSetForm):
    model = JournalEntry
    fieldsets = (
        (None, ('q', 'tag')),
        ('Creation', ('created_before', 'created_after', 'created_by_id')),
        ('Attributes', ('assigned_object_type_id', 'kind'))
    )
    created_after = forms.DateTimeField(
        required=False,
        label=_('After'),
        widget=DateTimePicker()
    )
    created_before = forms.DateTimeField(
        required=False,
        label=_('Before'),
        widget=DateTimePicker()
    )
    created_by_id = DynamicModelMultipleChoiceField(
        queryset=User.objects.all(),
        required=False,
        label=_('User'),
        widget=APISelectMultiple(
            api_url='/api/users/users/',
        )
    )
    assigned_object_type_id = DynamicModelMultipleChoiceField(
        queryset=ContentType.objects.all(),
        required=False,
        label=_('Object Type'),
        widget=APISelectMultiple(
            api_url='/api/extras/content-types/',
        )
    )
    kind = forms.ChoiceField(
        choices=add_blank_choice(JournalEntryKindChoices),
        required=False,
        widget=StaticSelect()
    )
    tag = TagFilterField(model)


class ObjectChangeFilterForm(FilterForm):
    model = ObjectChange
    fieldsets = (
        (None, ('q',)),
        ('Time', ('time_before', 'time_after')),
        ('Attributes', ('action', 'user_id', 'changed_object_type_id')),
    )
    time_after = forms.DateTimeField(
        required=False,
        label=_('After'),
        widget=DateTimePicker()
    )
    time_before = forms.DateTimeField(
        required=False,
        label=_('Before'),
        widget=DateTimePicker()
    )
    action = forms.ChoiceField(
        choices=add_blank_choice(ObjectChangeActionChoices),
        required=False,
        widget=StaticSelect()
    )
    user_id = DynamicModelMultipleChoiceField(
        queryset=User.objects.all(),
        required=False,
        label=_('User'),
        widget=APISelectMultiple(
            api_url='/api/users/users/',
        )
    )
    changed_object_type_id = DynamicModelMultipleChoiceField(
        queryset=ContentType.objects.all(),
        required=False,
        label=_('Object Type'),
        widget=APISelectMultiple(
            api_url='/api/extras/content-types/',
        )
    )

[(47, 'django.forms.IntegerField', 'forms.IntegerField', False, 'from django import forms\n'), (80, 'django.forms.IntegerField', 'forms.IntegerField', False, 'from django import forms\n'), (99, 'django.forms.CharField', 'forms.CharField', False, 'from django import forms\n'), (280, 'utilities.forms.TagFilterField', 'TagFilterField', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (38, 'django.contrib.contenttypes.models.ContentType.objects.all', 'ContentType.objects.all', False, 'from django.contrib.contenttypes.models import ContentType\n'), (39, 'extras.utils.FeatureQuery', 'FeatureQuery', False, 'from extras.utils import FeatureQuery\n'), (45, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (52, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (64, 'django.contrib.contenttypes.models.ContentType.objects.all', 'ContentType.objects.all', False, 'from django.contrib.contenttypes.models import ContentType\n'), (65, 'extras.utils.FeatureQuery', 'FeatureQuery', False, 'from extras.utils import FeatureQuery\n'), (70, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (76, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (91, 'django.contrib.contenttypes.models.ContentType.objects.all', 'ContentType.objects.all', False, 'from django.contrib.contenttypes.models import ContentType\n'), (92, 'extras.utils.FeatureQuery', 'FeatureQuery', False, 'from extras.utils import FeatureQuery\n'), (97, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (104, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (117, 'django.contrib.contenttypes.models.ContentType.objects.all', 'ContentType.objects.all', False, 'from django.contrib.contenttypes.models import ContentType\n'), (118, 'extras.utils.FeatureQuery', 'FeatureQuery', False, 'from extras.utils import FeatureQuery\n'), (124, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (128, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (134, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (140, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (146, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (157, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (170, 'dcim.models.Region.objects.all', 'Region.objects.all', False, 'from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup\n'), (172, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (175, 'dcim.models.SiteGroup.objects.all', 'SiteGroup.objects.all', False, 'from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup\n'), (177, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (180, 'dcim.models.Site.objects.all', 'Site.objects.all', False, 'from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup\n'), (182, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (185, 'dcim.models.DeviceType.objects.all', 'DeviceType.objects.all', False, 'from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup\n'), (187, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (190, 'dcim.models.DeviceRole.objects.all', 'DeviceRole.objects.all', False, 'from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup\n'), (192, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (195, 'dcim.models.Platform.objects.all', 'Platform.objects.all', False, 'from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup\n'), (197, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (200, 'virtualization.models.ClusterType.objects.all', 'ClusterType.objects.all', False, 'from virtualization.models import Cluster, ClusterGroup, ClusterType\n'), (202, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (206, 'virtualization.models.ClusterGroup.objects.all', 'ClusterGroup.objects.all', False, 'from virtualization.models import Cluster, ClusterGroup, ClusterType\n'), (208, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (211, 'virtualization.models.Cluster.objects.all', 'Cluster.objects.all', False, 'from virtualization.models import Cluster, ClusterGroup, ClusterType\n'), (213, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (216, 'tenancy.models.TenantGroup.objects.all', 'TenantGroup.objects.all', False, 'from tenancy.models import Tenant, TenantGroup\n'), (218, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (221, 'tenancy.models.Tenant.objects.all', 'Tenant.objects.all', False, 'from tenancy.models import Tenant, TenantGroup\n'), (223, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (228, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (235, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (236, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (251, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (252, 'utilities.forms.DateTimePicker', 'DateTimePicker', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (256, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (257, 'utilities.forms.DateTimePicker', 'DateTimePicker', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (260, 'django.contrib.auth.models.User.objects.all', 'User.objects.all', False, 'from django.contrib.auth.models import User\n'), (262, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (263, 'utilities.forms.APISelectMultiple', 'APISelectMultiple', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (268, 'django.contrib.contenttypes.models.ContentType.objects.all', 'ContentType.objects.all', False, 'from django.contrib.contenttypes.models import ContentType\n'), (270, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (271, 'utilities.forms.APISelectMultiple', 'APISelectMultiple', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (276, 'utilities.forms.add_blank_choice', 'add_blank_choice', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (278, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (292, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (293, 'utilities.forms.DateTimePicker', 'DateTimePicker', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (297, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (298, 'utilities.forms.DateTimePicker', 'DateTimePicker', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (301, 'utilities.forms.add_blank_choice', 'add_blank_choice', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (303, 'utilities.forms.StaticSelect', 'StaticSelect', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (306, 'django.contrib.auth.models.User.objects.all', 'User.objects.all', False, 'from django.contrib.auth.models import User\n'), (308, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (309, 'utilities.forms.APISelectMultiple', 'APISelectMultiple', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (314, 'django.contrib.contenttypes.models.ContentType.objects.all', 'ContentType.objects.all', False, 'from django.contrib.contenttypes.models import ContentType\n'), (316, 'django.utils.translation.gettext', '_', True, 'from django.utils.translation import gettext as _\n'), (317, 'utilities.forms.APISelectMultiple', 'APISelectMultiple', False, 'from utilities.forms import add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, TagFilterField\n'), (155, 'extras.utils.FeatureQuery', 'FeatureQuery', False, 'from extras.utils import FeatureQuery\n')]