from django import forms from django.db.models import Q from django.utils.translation import gettext_lazy as _ import crispy_forms.bootstrap as bootstrap from syntax.models_phrase import PhraseTypeModel from semantics.models import ( Frame, SemanticRole, RoleAttribute, PredefinedSelectionalPreference, Synset, RelationalSelectionalPreference, SelectionalPreferenceRelation, ) from .generic_fields import ( RadiosLayoutField, SingleRegexFilter, ModelChoiceFilter, ModelMultipleChoiceFilter, ) from .query_managers import ( QueryManager, DUMMY_LOOKUP, ) from entries.polish_strings import PHRASE_TYPE class PhraseTypeFilter(ModelChoiceFilter): def __init__(self, queryset=None, lex=False, **kwargs): if queryset is None: if lex: queryset = PhraseTypeModel.objects.filter(main_phrase_types__lex_phrases__isnull=False).distinct() else: queryset = PhraseTypeModel.objects.filter(main_phrase_types__positions__isnull=False).distinct() super().__init__( label=(_('Typ frazy zleksykalizowanej') if lex else _('Typ frazy')), queryset=queryset, key='name', # this field is not used for filtering, only for choosing subform type lookup=DUMMY_LOOKUP, # we will want to identify the selected phrase type by name later to_field_name='name', empty_label=_('wybierz'), **kwargs, ) def label_from_instance(self, obj): pt = obj.name return '{} ({})'.format(pt, PHRASE_TYPE().get(pt, '...')) # TODO implementation without internal QueryManager subclass? # TODO possibly refactor and check class PhraseoFilter(forms.ChoiceField, RadiosLayoutField): class PhraseoQueryManager(QueryManager): def __init__(self): super().__init__(None, None) # Assumes this filter is used on either Entry or Schema and uses the # fact that both have the same related name for Subentry def _make_queries(self, _, value, op): if value == '1': return [Q(subentries__schemata__phraseologic=True)] if value == '0': return [~Q(subentries__schemata__phraseologic=True)] return [] def __init__(self): super().__init__( label=_('Frazeologia'), choices=(('2', _('dowolnie')), ('1', _('zawiera')), ('0', _('nie zawiera'))), initial='2', required=False, ) self.query_manager = PhraseoFilter.PhraseoQueryManager() # crispy_forms/bootstap.py class RoleCheckboxes(bootstrap.Field): template = 'role_checkboxselectmultiple.html' class RoleFilter(ModelMultipleChoiceFilter): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # choice: (value, (label, tooltip_text)) self.choices_index = { choice[1][0] : choice for choice in self.choices } def layout(self, x, **kwargs): return RoleCheckboxes(x, **kwargs) def _choices_group(self, *choice_names): return [self.choices_index[x] for x in choice_names] def header(self): raise NotImplementedError def rows(self): raise NotImplementedError class RoleNameFilter(RoleFilter): def __init__(self, label, lookup, **kwargs): super().__init__( label=label, #queryset=SemanticRole.objects.filter(argumentrole__argument__isnull=False).distinct(), queryset=SemanticRole.objects.all(), key='role', lookup=lookup, **kwargs, ) def header(self): return ('', _('inicjujące'), _('towarzyszące'), _('zamykające')) def rows(self): return ( { 'name': _('podstawowe'), 'cols': ( self._choices_group('Initiator', 'Stimulus'), self._choices_group('Theme', 'Experiencer', 'Factor', 'Instrument'), self._choices_group('Recipient', 'Result'), ) }, { 'name': _('uzupełniające'), 'cols': ( self._choices_group('Condition'), self._choices_group('Attribute', 'Manner', 'Measure', 'Location', 'Path', 'Time', 'Duration'), self._choices_group('Purpose'), ) }, ) class RoleAttributeFilter(RoleFilter): def __init__(self, label, lookup, **kwargs): super().__init__( label=label, #queryset=RoleAttribute.objects.filter(argumentrole__argument__isnull=False).distinct(), queryset=RoleAttribute.objects.all(), key='attribute', lookup=lookup, **kwargs, ) def header(self): return None def rows(self): return ( { 'name': '', 'cols': ( self._choices_group('Source'), self._choices_group('Foreground', 'Background'), self._choices_group('Goal'), ) }, )