Ticket #5407: many2manywidget.diff

File many2manywidget.diff, 4.2 KB (added by xian, 17 years ago)
  • media/js/admin/RelatedObjectLookups.js

     
    1919function dismissRelatedLookupPopup(win, chosenId) {
    2020    var name = win.name.replace(/___/g, '.');
    2121    var elem = document.getElementById(name);
    22     if (elem.className.indexOf('vRawIdAdminField') != -1 && elem.value) {
     22    if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
    2323        elem.value += ',' + chosenId;
    2424    } else {
    2525        document.getElementById(name).value = chosenId;
  • options.py

     
    168168        if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
    169169            if isinstance(db_field, models.ForeignKey) and db_field.name in self.raw_id_fields:
    170170                kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)
    171                 return db_field.formfield(**kwargs)
    172171            else:
    173                 # Wrap the widget's render() method with a method that adds
    174                 # extra HTML to the end of the rendered output.
    175                 formfield = db_field.formfield(**kwargs)
    176                 formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel, self.admin_site)
    177                 return formfield
     172                if isinstance(db_field, models.ManyToManyField) and db_field.name in self.raw_id_fields:
     173                    kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel)
     174                    kwargs['help_text'] = ''
     175            # Wrap the widget's render() method with a method that adds
     176            # extra HTML to the end of the rendered output.
     177            formfield = db_field.formfield(**kwargs)
     178            formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel, self.admin_site)
     179            return formfield
    178180
    179181        # For any other type of field, just call its formfield() method.
    180182        return db_field.formfield(**kwargs)
  • widgets.py

     
    33"""
    44
    55from django import newforms as forms
     6from django.utils.datastructures import MultiValueDict
    67from django.utils.text import capfirst
    78from django.utils.translation import ugettext as _
    89from django.conf import settings
     
    7576            url = '?' + '&'.join(['%s=%s' % (k, v) for k, v in self.rel.limit_choices_to.items()])
    7677        else:
    7778            url = ''
    78         attrs['class'] = 'vRawIdAdminField' # The JavaScript looks for this hook.
     79        if not attrs.has_key('class'):
     80          attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
    7981        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
    8082        # TODO: "id_" is hard-coded here. This should instead use the correct
    8183        # API to determine the ID dynamically.
     
    8587        return u''.join(output)
    8688        #if self.change: # TODO
    8789            #output.append('&nbsp;<strong>TODO</strong>')
     90           
     91class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
     92    """
     93    A Widget for displaying ManyToMany ids in the "raw_id" interface rather than
     94    in a <select multiple> box.
     95    """
     96    def __init__(self, rel, attrs=None):
     97        super(ManyToManyRawIdWidget, self).__init__(rel, attrs)
     98   
     99    def render(self, name, value, attrs=None):
     100        attrs['class'] = 'vManyToManyRawIdAdminField'
     101        if value:
     102            value = ','.join(value)
     103        else:
     104            value = ""
     105        return super(ManyToManyRawIdWidget, self).render(name, value, attrs)
    88106
     107    def value_from_datadict(self, data, files, name):
     108        if isinstance(data, MultiValueDict):
     109            return data[name].split(',')
     110        return data.get(name, None)
     111
    89112class RelatedFieldWidgetWrapper(object):
    90113    """
    91114    This class is a wrapper whose __call__() method mimics the interface of a
Back to Top