Skip to content

Commit 911b0b4

Browse files
committed
[gsoc2009/admin-ui] Refactored the m2m token input view a bit to make it cleaner, and now properly prepopulating data for the m2m token input widget
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/admin-ui@11928 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent 9831258 commit 911b0b4

File tree

2 files changed

+27
-25
lines changed

2 files changed

+27
-25
lines changed

django/contrib/admin/templates/widget/m2m_searchinput.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44
</a>
55
<script type="text/javascript">
66
$(document).ready(function() {
7+
$('#id_{{ name }}').val('');
78
$('#id_{{ name }}').tokenInput("{{ search_path }}", {
89
noResultsText: "No results found.",
9-
searchingText: "Searching..."
10+
searchingText: "Searching...",
11+
prePopulate: [
12+
{% for p in prepopulated_data %}
13+
{id: {{ p.id }}, name: "{{ p.name }}"},
14+
{% endfor %}
15+
]
1016
});
1117

1218
$('#add_id_{{ name }}').hide();

django/contrib/admin/widgets.py

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -289,56 +289,52 @@ def __init__(self, rel, search_fields, attrs=None):
289289
self.search_fields = search_fields
290290
super(ManyToManySearchInput, self).__init__(rel, attrs)
291291

292-
def label_for_value(self, value):
292+
def prepopulated_data_for_value(self, value):
293293
key = self.rel.get_related_field().name
294-
objs = self.rel.to._default_manager.filter(**{key + '__in': value.split(',')})
295-
return ','.join([str(o) for o in objs])
294+
objs = self.rel.to._default_manager.filter(**{key + '__in': value})
295+
return [{'id': o.id, 'name': unicode(o)} for o in objs]
296296

297297
def get_search_path(self, name):
298298
return '../autocomplete/%s/' % name
299299

300300
def render(self, name, value, attrs=None):
301301
if attrs is None:
302302
attrs = {}
303-
output = [super(ManyToManySearchInput, self).render(name, value, attrs)]
304-
if value:
305-
value = ','.join([str(v) for v in value])
306-
else:
307-
value = ''
308-
opts = self.rel.to._meta
309-
app_label = opts.app_label
310-
model_name = opts.object_name.lower()
311-
related_url = '../../../%s/%s/' % (app_label, model_name)
303+
if not attrs.has_key('class'):
304+
attrs['class'] = 'vM2MRawIdAdminField'
305+
306+
if not value:
307+
value = []
308+
312309
params = self.url_parameters()
313310
if params:
314311
url = '?' + '&amp;'.join(['%s=%s' % (k, v) for k, v in params.items()])
315312
else:
316313
url = ''
317-
if not attrs.has_key('class'):
318-
attrs['class'] = 'vM2MRawIdAdminField'
319-
# Call the TextInput render method directly to have more control
320-
output = [forms.TextInput.render(self, name, value, attrs)]
321-
if value:
322-
label = self.label_for_value(value)
323-
else:
324-
label = u''
314+
315+
output = [forms.TextInput.render(self, name, ','.join([str(v) for v in value]), attrs)]
316+
opts = self.rel.to._meta
317+
325318
context = {
326319
'url': url,
327-
'related_url': related_url,
320+
'related_url': '../../../%s/%s/' % (opts.app_label, opts.object_name.lower()),
328321
'admin_media_prefix': settings.ADMIN_MEDIA_PREFIX,
329322
'search_path': self.get_search_path(name),
330323
'search_fields': ','.join(self.search_fields),
331-
'model_name': model_name,
332-
'app_label': app_label,
333-
'label': label,
334324
'name': name,
325+
'model_name': opts.object_name.lower(),
326+
'app_label': opts.app_label,
327+
'prepopulated_data': self.prepopulated_data_for_value(value),
335328
}
329+
336330
output.append(render_to_string(self.widget_template or (
337331
'templates/widget/%s/%s/m2m_searchinput.html' % (app_label, model_name),
338332
'templates/widget/%s/m2m_searchinput.html' % app_label,
339333
'templates/widget/m2m_searchinput.html',
340334
), context))
335+
341336
output.reverse()
337+
342338
return mark_safe(u''.join(output))
343339

344340
class RelatedFieldWidgetWrapper(forms.Widget):

0 commit comments

Comments
 (0)