def __init__(self, model, lookups, default_index=0, select_related=None, widget=FilteredSelect, *args, **kwargs): """ See the AjaxManyToManyField docstring. """ # get the default index and queryset # queryset is empty if default index is None if default_index is None: queryset = model.objects.none() else: lookups_list = utils.getLookups(lookups) lookup_dict = lookups_list[default_index][1] # get the queryset queryset = utils.getObjects(model, lookup_dict, select_related) # call the parent constructor super(AjaxForeignKeyField, self).__init__(queryset, widget=widget, *args, **kwargs) # populate widget with some data self.widget.lookups = self.lookups = lookups self.widget.model = self.model = model self.widget.select_related = select_related
def __init__(self, model, lookups, default_index=0, select_related=None, widget=FilteredSelectMultiple, *args, **kwargs): """ model: the related model lookups: a sequence of (label, lookup_dict) that tells how to filter the objects e.g. ( ('active', {'is_active': True}), ('inactive', {'is_active': False}), ) you may specify what you want in lookup_dict, give multiple filter lookups for the same choice and also set a choice that gets all unfiltered objects e.g. ( ('some stuff', { 'field1__startswith': 'a', 'field2': 'value' }), ('all stuff', {}), ) default_index: the index of the lookup sequence that will be the default choice when the field is initially displayed. set to None if you want the widget to start empty select_related: if not None the resulting querydict is performed using select_related(select_related), allowing foreign keys to be retrieved (e.g. useful when the unicode representation of the model objects contains references to foreign keys) It is possible to pass all the other args and kwargs accepted by the django field class. """ # get the default index and queryset # queryset is empty if default index is None if default_index is None: queryset = model.objects.none() else: lookups_list = utils.getLookups(lookups) lookup_dict = lookups_list[default_index][1] # get the queryset queryset = utils.getObjects(model, lookup_dict, select_related) # call the parent constructor super(AjaxManyToManyField, self).__init__(queryset, widget=widget, *args, **kwargs) # populate widget with some data self.widget.lookups = self.lookups = lookups self.widget.model = self.model = model self.widget.select_related = select_related
def to_python(self, value): if value in forms.fields.EMPTY_VALUES: return None # if there is only one lookup used to limit choices, then a real # validation over that limited choices is performed lookups_list = utils.getLookups(self.lookups) limit_choices_to = {} if len(lookups_list) != 1 else lookups_list[0][1] try: key = self.to_field_name or 'pk' limit_choices_to[key] = value value = self.model.objects.get(**limit_choices_to) except (ValueError, self.queryset.model.DoesNotExist): raise ValidationError(self.error_messages['invalid_choice']) return value
def __init__(self, model, lookups, default_index=0, select_related=None, widget=FilteredSelectMultiple, *args, **kwargs): """ model: the related model lookups: a sequence of (label, lookup_dict) that tells how to filter the objects e.g. ( ('active', {'is_active': True}), ('inactive', {'is_active': False}), ) you may specify what you want in lookup_dict, give multiple filter lookups for the same choice and also set a choice that gets all unfiltered objects e.g. ( ('some stuff', { 'field1__startswith': 'a', 'field2': 'value' }), ('all stuff', {}), ) default_index: the index of the lookup sequence that will be the default choice when the field is initially displayed. set to None if you want the widget to start empty select_related: if not None the resulting querydict is performed using select_related(select_related), allowing foreign keys to be retrieved (e.g. useful when the unicode representation of the model objects contains references to foreign keys) It is possible to pass all the other args and kwargs accepted by the django field class. """ # get the default index and queryset # queryset is empty if default index is None if default_index is None: queryset = model.objects.none() else: lookups_list = utils.getLookups(lookups) lookup_dict = lookups_list[default_index][1] # get the queryset queryset = utils.getObjects(model, lookup_dict, select_related) # call the parent constructor super(AjaxManyToManyField, self ).__init__(queryset, widget=widget, *args, **kwargs) # populate widget with some data self.widget.lookups = self.lookups = lookups self.widget.model = self.model = model self.widget.select_related = select_related self.widget.field_name = self.field_name
def clean(self, value): if value in forms.fields.EMPTY_VALUES: return None # if there is only one lookup used to limit choices, then a real # validation over that limited choices is performed lookups_list = utils.getLookups(self.lookups) limit_choices_to = {} if len(lookups_list) != 1 else lookups_list[0][1] try: key = self.to_field_name or 'pk' limit_choices_to[key] = value value = self.model.objects.get(**limit_choices_to) except self.model.DoesNotExist: raise ValidationError(self.error_messages['invalid_choice']) return value
def render(self, name, value, attrs=None, choices=()): self._element_id = attrs['id'] # choices links # if there is only one choice, then nothing will be rendered lookups_output = "" lookups = utils.getLookups(self.lookups) if len(lookups) > 1: js_method_name = "getManyToManyJSON" lookups_output = "\n".join( _renderFilter(js_method_name, self._element_id, self.model, i, self.select_related) for i in lookups) # normal widget output from the anchestor self.choices = self._getAllChoices(value) parent_output = super(FilteredSelectMultiple, self ).render(name, value, attrs, choices) # create the output including the django admin's Javascript code that # mutates the select widget into a selectfilter one # this assumes that /admin/jsi18n/, core.js, SelectBox.js and # SelectFilter2.js are loaded from the page verbose_name = self.model._meta.verbose_name_plural.replace('"', '\\"') output = u""" <div id="%s_filter_many"> %s </div> %s <script type="text/javascript"> $(function(){ SelectFilter.init("id_%s", "%s", 0, "%s"); // Move the filters to within the first select box. var e = $("#%s_filter_many").hide(); e.siblings('.selector').find('.selector-available > h2').after($("<h2/>").addClass('ajax-filters').append(e.html())); e.remove(); }); </script> """ % (name, lookups_output, parent_output, name, verbose_name, settings.ADMIN_MEDIA_PREFIX, name) return mark_safe(output)
def clean(self, value): if self.required and not value: raise ValidationError(self.error_messages['required']) elif not self.required and not value: return [] if not isinstance(value, (list, tuple)): raise ValidationError(self.error_messages['list']) final_values = [] # if there is only one lookup used to limit choices, then a real # validation over that limited choices is performed lookups_list = utils.getLookups(self.lookups) limit_choices_to = {} if len(lookups_list) != 1 else lookups_list[0][1] for val in value: try: obj = self.model.objects.get(pk=val, **limit_choices_to) except self.model.DoesNotExist: raise ValidationError(self.error_messages['invalid_choice'] % val) else: final_values.append(obj) return final_values
def __init__(self, model, lookups, qs, default_index=0, select_related=None, widget=widget_fs_mod, *args, **kwargs): """ See the AjaxManyToManyField docstring. """ # get the default index and queryset # queryset is empty if default index is None if default_index is None: queryset = model.objects.none() else: lookups_list = utils.getLookups(lookups) lookup_dict = lookups_list[default_index][1] # get the queryset queryset = utils.getObjects(model, lookup_dict, select_related) # call the parent constructor super(AjaxForeignKeyField, self ).__init__(qs, widget=widget, *args, **kwargs) # populate widget with some data self.widget.lookups = self.lookups = lookups self.widget.model = self.model = model self.widget.select_related = select_related
def render(self, name, value, attrs=None, choices=()): self._element_id = attrs['id'] # choices links # if there is only one choice, then nothing will be rendered lookups_output = "" lookups = utils.getLookups(self.lookups) if len(lookups) > 1: js_method_name = "getManyToManyJSON" lookups_output = "\n".join( _renderFilter(js_method_name, self._element_id, self.model, i, self.select_related) for i in lookups) # normal widget output from the anchestor self.choices = self._getAllChoices(value) parent_output = super(FilteredSelectMultiple, self ).render(name, value, attrs, choices) # create the output including the django admin's Javascript code that # mutates the select widget into a selectfilter one # this assumes that /admin/jsi18n/, core.js, SelectBox.js and # SelectFilter2.js are loaded from the page verbose_name = self.model._meta.verbose_name_plural.replace('"', '\\"') ADMIN_URL = settings.STATIC_URL + "admin/" output = u""" <div> <ul>%s</ul> </div> %s <script type="text/javascript"> $(document).ready(function(){ SelectFilter.init("id_%s", "%s", 0, "%s"); }); </script> """ % (lookups_output, parent_output, name, verbose_name, ADMIN_URL) return mark_safe(output)
def render(self, name, value, attrs=None, choices=()): self._element_id = attrs['id'] # choices links # if there is only one choice, then nothing will be rendered lookups_output = "" lookups = utils.getLookups(self.lookups) if len(lookups) > 1: js_method_name = "getManyToManyJSON" lookups_output = "\n".join( _renderFilter(js_method_name, self._element_id, self.model, i, self.select_related) for i in lookups) # normal widget output from the anchestor self.choices = self._getAllChoices(value) parent_output = super(FilteredSelectMultiple, self).render(name, value, attrs, choices) # create the output including the django admin's Javascript code that # mutates the select widget into a selectfilter one # this assumes that /admin/jsi18n/, core.js, SelectBox.js and # SelectFilter2.js are loaded from the page verbose_name = self.model._meta.verbose_name_plural.replace('"', '\\"') output = u""" <div> %s </div> %s <script type="text/javascript"> (function($) { $(document).ready(function(){ SelectFilter.init("id_%s", "%s", 0); }); })(django.jQuery); </script> """ % (lookups_output, parent_output, name, verbose_name) return mark_safe(output)
def render(self, name, value, attrs=None, choices=()): self._element_id = attrs['id'] # choices links # if there is only one choice, then nothing will be rendered lookups_output = "" lookups = utils.getLookups(self.lookups) if len(lookups) > 1: js_method_name = "getForeignKeyJSON" lookups_output = "\n".join( _renderFilter(js_method_name, self._element_id, self.model, i, self.select_related) for i in lookups) # get the selected object name selection = "-" * 9 if value: selection = utils.getObject(self.model, {"pk": value}, self.select_related) # filter selectbox input filter_id = "%s_input" % self._element_id # give a style to the final select widget _attrs = {"size": 2, "style": "width:270px;"} try: attrs.update(_attrs) except AttributeError: attrs = _attrs # normal widget output from the anchestor # create a field with a dummy name , the real value # will be retrieved from a hidden field parent_output = super(FilteredSelect, self).render("dummy-%s" % name, value, attrs, choices) # output mapping = { "lookups_output": lookups_output, "selection": selection, "filter_id": filter_id, "parent_output": parent_output, "name": name, "element_id": self._element_id, "value": "" if value is None else value, "static_url": settings.STATIC_URL, } output = u""" <div class="selector"> %(lookups_output)s </div> <div class="selector"> <div class="selector-available"> <h2>%(selection)s</h2> <p class="selector-filter"> <img src="%(static_url)sadmin/img/search.svg"> <input id="%(filter_id)s" type="text"> </p> %(parent_output)s </div> </div> <input type="hidden" name="%(name)s" id="hidden-%(element_id)s" value="%(value)s" /> <script type="text/javascript" charset="utf-8"> (function($) { $(document).ready(function(){ SelectBox.init('%(element_id)s'); $("#%(filter_id)s").bind("keyup", function(e) { SelectBox.filter("%(element_id)s", $("#%(filter_id)s").val()) }); $(".ajax_letter").click(function(e) { $("#%(filter_id)s").val(""); }); ajax_filtered_fields.bindForeignKeyOptions("%(element_id)s"); }); })(django.jQuery); </script> """ % mapping return mark_safe(output)
def render(self, name, value, attrs=None, choices=()): self._element_id = attrs['id'] # choices links # if there is only one choice, then nothing will be rendered lookups_output = "" lookups = utils.getLookups(self.lookups) if len(lookups) > 1: js_method_name = "getForeignKeyJSON" lookups_output = "\n".join( _renderFilter(js_method_name, self._element_id, self.model, i, self.select_related) for i in lookups) # get the selected object name selection = "-" * 9 if value: selection = utils.getObject(self.model, {"pk": value}, self.select_related) # filter selectbox input filter_id = "%s_input" % self._element_id # give a style to the final select widget _attrs = {"size": 2, "style": "width:670px;"} try: attrs.update(_attrs) except AttributeError: attrs = _attrs # normal widget output from the anchestor # create a field with a dummy name , the real value # will be retrieved from a hidden field parent_output = super(FilteredSelect, self ).render("dummy-%s" % name, value, attrs, choices) # output mapping = { "lookups_output": lookups_output, "selection": selection, "filter_id": filter_id, "parent_output": parent_output, "name": name, "element_id": self._element_id, "value": "" if value is None else value, } output = u""" <div class="selector"> %(lookups_output)s </div> <div class="selector"> <div class="selector-available"> <h2>%(selection)s</h2> <p class="selector-filter"> <img src="/media/img/admin/selector-search.gif"> <input id="%(filter_id)s" type="text"> </p> %(parent_output)s </div> </div> <input type="hidden" name="%(name)s" id="hidden-%(element_id)s" value="%(value)s" /> <script type="text/javascript" charset="utf-8"> $(document).ready(function(){ SelectBox.init('%(element_id)s'); $("#%(filter_id)s").bind("keyup", function(e) { SelectBox.filter("%(element_id)s", $("#%(filter_id)s").val()) }); $(".ajax_letter").click(function(e) { $("#%(filter_id)s").val(""); }); ajax_filtered_fields.bindForeignKeyOptions("%(element_id)s"); }); </script> """ % mapping return mark_safe(output)
def render(self, name, value, attrs=None, choices=()): self._element_id = attrs['id'] # choices links # if there is only one choice, then nothing will be rendered lookups_output = "" lookups = utils.getLookups(self.lookups) if len(lookups) > 1: js_method_name = "getManyToManyJSON" lookups_output = "\n".join( _renderFilter(js_method_name, self._element_id, self.model, i, self.select_related) for i in lookups) # normal widget output from the anchestor self.choices = self._getAllChoices(value) parent_output = super(FilteredSelectMultiple, self ).render(name, value, attrs, choices) # create the output including the django admin's Javascript code that # mutates the select widget into a selectfilter one # this assumes that /admin/jsi18n/, core.js, SelectBox.js and # SelectFilter2.js are loaded from the page verbose_name = self.model._meta.verbose_name_plural.replace('"', '\\"') element_id = self._element_id model_name = self.model._meta.object_name app_name = self.model._meta.app_label #Mohammed: modified for better display, option to add, and to filter select list via AJAX calls output = u""" <p class="help"> filter by: %s <em>limited to 100 results</em> </p> %s <script type="text/javascript"> $(document).ready(function(){ SelectFilter.init("id_%s", "%s", 0, "%s"); var timer $("#%s_input").keyup( function(event){ clearTimeout(timer) var that = this timer = setTimeout(function() { if($(that).val().length >=2) { ajax_filtered_fields.%s('%s', '%s', '%s', '%s__istartswith=' + $(that).val(), 'None') } }, 250) }); $("#%s_input").keyup( function(event){ clearTimeout(timer) var that = this timer = setTimeout(function() { if($(that).val().length >=2) { ajax_filtered_fields.%s('%s', '%s', '%s', '%s__istartswith=' + $(that).val(), 'None') } }, 250) }); }); </script> <a href="/admin/%s/%s/add/" class="add-another" id="add_%s" onclick="return showAddAnotherPopup(this);"> <img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"></a> """ % (lookups_output, parent_output, name, verbose_name, settings.ADMIN_MEDIA_PREFIX, element_id, js_method_name, element_id, app_name, model_name, self.field_name, element_id, js_method_name, element_id, app_name, model_name, self.field_name, app_name, model_name.lower(), self._element_id, settings.ADMIN_MEDIA_PREFIX, ) return mark_safe(output)