raw_id_fields for modelforms
You need to change the widget for the base
field, not the field type. I think this would work:
class OpBaseForm(ModelForm):
base = forms.ModelChoiceField(queryset=Base.objects.all(),
widget=forms.TextInput)
class Meta:
model = OpBase
... etc...
You can also use the entire raw_id_field admin widget, complete with the handy js popup search that the admin page has. You don't even need a model form. Here's how:
import string
from django.contrib.admin.widgets import ForeignKeyRawIdWidget
from django import forms
from models import MyModel
# Have to subclass widget b/c
# django hardcodes a relative path to Admin Root URL: ../../..
class HardcodedURLForeignKeyRawIdWidget(ForeignKeyRawIdWidget):
def render(self, *args, **kwargs):
original_render = super(HardcodedURLForeignKeyRawIdWidget,
self).render(*args, **kwargs)
ADMIN_ROOT_URL = "/admin/"
return string.replace(original_render,"../../../", ADMIN_ROOT_URL)
class FieldLookupForm(forms.Form):
my_foreignkey_field = forms.CharField(max_length=10,
widget=HardcodedURLForeignKeyRawIdWidget(
MyModel._meta.get_field("foreignkey_field").rel))
Add the relevant admin js to your template, and viola
{% block header %}
<script type="text/javascript">window.__admin_media_prefix__ = "/static/admin/";</script>
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/static/admin/js/core.js"></script>
<script type="text/javascript" src="/static/admin/js/admin/RelatedObjectLookups.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
<script type="text/javascript" src="/static/admin/js/actions.min.js"></script>
{% endblock %}
To expand on Voltaire's comment above, the django 1.4 solution is:
from django.contrib import admin
admin.autodiscover()
from django.contrib.admin.widgets import ForeignKeyRawIdWidget
from django import forms
from .models import Post, Photo
class PostForm(forms.ModelForm):
photo = forms.ModelChoiceField(
Photo.objects.all(),
widget=ForeignKeyRawIdWidget(Post._meta.get_field("photo").rel,admin.site)
)
And the only additional javascript you should need is:
<script type="text/javascript" src="/static/admin/js/admin/RelatedObjectLookups.js"></script>
The important thing here is that you call autodiscover on the admin, otherwise your RawIdWidget won't have a link. Also the ModelChoiceField requires a queryset, which isn't actually used. ModelChoiceField is preferable to CharField because CharField doesn't validate properly (tries to save the id rather than looking up the Photo instance).
Update
Django 2.0 deprecated Field.rel
in favor of Field.remote_field
.
That widget=
line will now need to be:
widget=ForeignKeyRawIdWidget(Post._meta.get_field("photo").remote_field, admin.site),