diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 15c9745f83..4925eeff76 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -207,16 +207,29 @@ class ModelAdmin(object):
if isinstance(db_field, models.ManyToManyField) and db_field.rel.filter_interface:
widget = widgets.FilteredSelectMultiple(db_field.verbose_name, db_field.rel.filter_interface-1)
return db_field.formfield(widget=widget, **kwargs)
+
# For DateTimeFields, use a special field and widget.
if isinstance(db_field, models.DateTimeField):
return forms.SplitDateTimeField(required=not db_field.blank,
widget=widgets.AdminSplitDateTime(), label=capfirst(db_field.verbose_name), **kwargs)
+
# For DateFields, add a custom CSS class.
if isinstance(db_field, models.DateField):
return db_field.formfield(widget=forms.TextInput(attrs={'class': 'vDateField', 'size': '10'}))
+
# For TimeFields, add a custom CSS class.
if isinstance(db_field, models.TimeField):
return db_field.formfield(widget=forms.TextInput(attrs={'class': 'vTimeField', 'size': '8'}))
+
+ # For ForeignKey or ManyToManyFields, use a special widget.
+ if db_field.rel and isinstance(db_field.rel, (models.ManyToOneRel, models.ManyToManyRel)):
+ # Wrap the widget's render() method with a method that adds
+ # extra HTML to the end of the rendered output.
+ formfield = db_field.formfield()
+ formfield.widget.render = widgets.RelatedFieldWidgetWrapper(formfield.widget.render, db_field.rel)
+ return formfield
+
+ # For any other type of field, just call its formfield() method.
return db_field.formfield(**kwargs)
def has_add_permission(self, request):
diff --git a/django/contrib/admin/templates/widget/foreign.html b/django/contrib/admin/templates/widget/foreign.html
index 301f5214db..476fdb9b37 100644
--- a/django/contrib/admin/templates/widget/foreign.html
+++ b/django/contrib/admin/templates/widget/foreign.html
@@ -1,15 +1,5 @@
{% load admin_modify adminmedia %}
{% output_all bound_field.form_fields %}
-{% if bound_field.raw_id_admin %}
- {% if bound_field.field.rel.limit_choices_to %}
-
- {% else %}
-
- {% endif %}
-{% else %}
-{% if bound_field.needs_add_label %}
-
-{% endif %}{% endif %}
{% if change %}
{% if bound_field.field.primary_key %}
{{ bound_field.original_value }}
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py
index 3a7c334301..b925693398 100644
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -63,12 +63,10 @@ class AdminBoundField(object):
self.field = field
self.original = original
self.form_fields = [field_mapping[name] for name in self.field.get_manipulator_field_names('')]
- self.element_id = self.form_fields[0].get_id()
self.has_label_first = not isinstance(self.field, models.BooleanField)
self.raw_id_admin = use_raw_id_admin(field)
self.is_date_time = isinstance(field, models.DateTimeField)
self.is_file_field = isinstance(field, models.FileField)
- self.needs_add_label = field.rel and (isinstance(field.rel, models.ManyToOneRel) or isinstance(field.rel, models.ManyToManyRel)) and field.rel.to._meta.admin
self.hidden = isinstance(self.field, models.AutoField)
self.first = False
@@ -81,9 +79,6 @@ class AdminBoundField(object):
self.cell_class_attribute = ' class="%s" ' % ' '.join(classes)
self._repr_filled = False
- if field.rel:
- self.related_url = '../../../%s/%s/' % (field.rel.to._meta.app_label, field.rel.to._meta.object_name.lower())
-
def original_value(self):
if self.original:
return self.original.__dict__[self.field.column]
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index e3f3e63c94..1a2abe85ce 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -40,3 +40,36 @@ class AdminSplitDateTime(forms.SplitDateTimeWidget):
def format_output(self, rendered_widgets):
return u'
%s %s
%s %s