예제 #1
0
	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 = utils.getLookups(self.lookups)
		lookups_output = self.filter_widget.renderFilter("getManyToManyJSON", self._element_id, self.model, lookups, self.select_related, self.default_index)
		
		# 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"""
			%s
			<script type="text/javascript">
				(function($) {
					$(document).ready(function(){
						SelectFilter.init("id_%s", "%s", 0, "%s");
					});
				})(django.jQuery);
			</script>
		""" % (self.filter_widget.composeField(lookups_output, parent_output), name, 
			verbose_name, settings.ADMIN_MEDIA_PREFIX)
		
		return mark_safe(output)
예제 #2
0
 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
예제 #3
0
    def __init__(
        self,
        model,
        lookups,
        default_index=0,
        select_related=None,
        widget=FilteredSelectMultiple,
        filter_widget=SelectBoxFilter,
        *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)
            if default_index >= len(lookups_list):
                default_index = 0
            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.filter_widget = filter_widget()
        self.widget.default_index = default_index