Skip to content

Commit 126c6ce

Browse files
newforms-admin: Backwards-incompatible change: Refactored prepopulate_from. There's no longer a 'prepopulate_from' option on database Field classes. Instead, there's a new 'prepopulated_fields' option on the 'class Admin'. This should be a dictionary mapping field names (as strings) to lists/tuples of field names that prepopulate them
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@4446 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent 54d2c54 commit 126c6ce

File tree

5 files changed

+31
-18
lines changed

5 files changed

+31
-18
lines changed

django/contrib/admin/options.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ def unquote(s):
3333
return "".join(res)
3434

3535
class AdminForm(object):
36-
def __init__(self, form, fieldsets):
36+
def __init__(self, form, fieldsets, prepopulated_fields):
3737
self.form, self.fieldsets = form, fieldsets
38+
self.prepopulated_fields = [{'field': form[field_name], 'dependencies': [form[f] for f in dependencies]} for field_name, dependencies in prepopulated_fields.items()]
3839

3940
def __iter__(self):
4041
for fieldset in self.fieldsets:
@@ -109,6 +110,7 @@ class ModelAdmin(object):
109110
js = None
110111
fields = None
111112
raw_id_fields = ()
113+
prepopulated_fields = {}
112114

113115
def __init__(self, model):
114116
self.model = model
@@ -145,9 +147,8 @@ def javascript(self, request, fieldsets):
145147
"""
146148
from django.conf import settings
147149
js = ['js/core.js', 'js/admin/RelatedObjectLookups.js']
148-
# TODO: This.
149-
#if auto_populated_fields:
150-
#js.append('js/urlify.js')
150+
if self.prepopulated_fields:
151+
js.append('js/urlify.js')
151152
if self.opts.has_field_type(models.DateTimeField) or self.opts.has_field_type(models.TimeField) or self.opts.has_field_type(models.DateField):
152153
js.extend(['js/calendar.js', 'js/admin/DateTimeShortcuts.js'])
153154
if self.opts.get_ordered_objects():
@@ -319,7 +320,7 @@ def add_view(self, request, form_url='', post_url_continue='../%s/'):
319320

320321
c = template.RequestContext(request, {
321322
'title': _('Add %s') % opts.verbose_name,
322-
'adminform': AdminForm(form, self.fieldsets_add(request)),
323+
'adminform': AdminForm(form, self.fieldsets_add(request), self.prepopulated_fields),
323324
'oldform': oldforms.FormWrapper(model.AddManipulator(), {}, {}),
324325
'is_popup': request.REQUEST.has_key('_popup'),
325326
'show_delete': False,
@@ -410,7 +411,7 @@ def change_view(self, request, object_id):
410411

411412
c = template.RequestContext(request, {
412413
'title': _('Change %s') % opts.verbose_name,
413-
'adminform': AdminForm(form, self.fieldsets_change(request, object_id)),
414+
'adminform': AdminForm(form, self.fieldsets_change(request, object_id), self.prepopulated_fields),
414415
'oldform': oldforms.FormWrapper(model.ChangeManipulator(object_id), {}, {}),
415416
'object_id': object_id,
416417
'original': obj,

django/contrib/admin/templates/admin/change_form.html

+14-4
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,20 @@
8383
<script type="text/javascript">document.getElementById("{{ adminform.first_field.auto_id }}").focus();</script>
8484
{% endif %}
8585

86-
{% if auto_populated_fields %}
87-
<script type="text/javascript">
88-
{% auto_populated_field_script auto_populated_fields change %}
89-
</script>
86+
{# JavaScript for prepopulated fields #}
87+
88+
{% if add %}
89+
<script type="text/javascript">
90+
{% for field in adminform.prepopulated_fields %}
91+
document.getElementById("{{ field.field.auto_id }}").onchange = function() { this._changed = true; };
92+
{% for dependency in field.dependencies %}
93+
document.getElementById("{{ dependency.auto_id }}").onkeyup = function() {
94+
var e = document.getElementById("{{ field.field.auto_id }}");
95+
if (!e._changed) { e.value = URLify({% for innerdep in field.dependencies %}document.getElementById("{{ innerdep.auto_id }}").value{% if not forloop.last %} + ' ' + {% endif %}{% endfor %}, {{ field.field.field.max_length }}); }
96+
}
97+
{% endfor %}
98+
{% endfor %}
99+
</script>
90100
{% endif %}
91101

92102
</div>

django/contrib/admin/views/main.py

-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ def original_url(self):
109109
def render_change_form(model_admin, model, manipulator, context, add=False, change=False, form_url=''):
110110
opts = model._meta
111111
app_label = opts.app_label
112-
auto_populated_fields = [f for f in opts.fields if f.prepopulate_from]
113112
original = getattr(manipulator, 'original_object', None)
114113
ordered_objects = opts.get_ordered_objects()
115114
inline_related_objects = opts.get_followed_related_objects(manipulator.follow)
@@ -120,7 +119,6 @@ def render_change_form(model_admin, model, manipulator, context, add=False, chan
120119
'has_change_permission': context['perms'][app_label][opts.get_change_permission()],
121120
'has_file_field': opts.has_field_type(models.FileField),
122121
'has_absolute_url': hasattr(model, 'get_absolute_url'),
123-
'auto_populated_fields': auto_populated_fields,
124122
'ordered_objects': ordered_objects,
125123
'inline_related_objects': inline_related_objects,
126124
'form_url': form_url,

django/core/management.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,6 @@ def get_validation_errors(outfile, app=None):
891891
from PIL import Image
892892
except ImportError:
893893
e.add(opts, '"%s": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name)
894-
if f.prepopulate_from is not None and type(f.prepopulate_from) not in (list, tuple):
895-
e.add(opts, '"%s": prepopulate_from should be a list or tuple.' % f.name)
896894
if f.choices:
897895
if not hasattr(f.choices, '__iter__'):
898896
e.add(opts, '"%s": "choices" should be iterable (e.g., a tuple or list).' % f.name)
@@ -979,6 +977,14 @@ def get_validation_errors(outfile, app=None):
979977

980978
# Check admin attribute.
981979
if opts.admin is not None:
980+
# prepopulated_fields
981+
if not isinstance(opts.admin.prepopulated_fields, dict):
982+
e.add(opts, '"%s": prepopulated_fields should be a dictionary.' % f.name)
983+
else:
984+
for field_name, field_list in opts.admin.prepopulated_fields.items():
985+
if not isinstance(field_list, (list, tuple)):
986+
e.add(opts, '"%s": prepopulated_fields "%s" value should be a list or tuple.' % (f.name, field_name))
987+
982988
# list_display
983989
if not isinstance(opts.admin.list_display, (list, tuple)):
984990
e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.')

django/db/models/fields/__init__.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,8 @@ class Field(object):
6868
def __init__(self, verbose_name=None, name=None, primary_key=False,
6969
maxlength=None, unique=False, blank=False, null=False, db_index=False,
7070
core=False, rel=None, default=NOT_PROVIDED, editable=True,
71-
prepopulate_from=None, unique_for_date=None, unique_for_month=None,
72-
unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
73-
help_text='', db_column=None):
71+
unique_for_date=None, unique_for_month=None, unique_for_year=None,
72+
validator_list=None, choices=None, radio_admin=None, help_text='', db_column=None):
7473
self.name = name
7574
self.verbose_name = verbose_name
7675
self.primary_key = primary_key
@@ -79,7 +78,6 @@ def __init__(self, verbose_name=None, name=None, primary_key=False,
7978
self.core, self.rel, self.default = core, rel, default
8079
self.editable = editable
8180
self.validator_list = validator_list or []
82-
self.prepopulate_from = prepopulate_from
8381
self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month
8482
self.unique_for_year = unique_for_year
8583
self._choices = choices or []

0 commit comments

Comments
 (0)