Opened 14 years ago
Last modified 4 years ago
#17881 new New feature
Implement BaseModelAdmin.get_raw_id_fields, similar to get_readonly_fields
| Reported by: | Aymeric Augustin | Owned by: | nobody |
|---|---|---|---|
| Component: | contrib.admin | Version: | 1.4-beta-1 |
| Severity: | Normal | Keywords: | raw_id_fields |
| Cc: | kmike84@…, romain.garrigues.cs@…, elonzh | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | yes |
| Needs tests: | yes | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
In order to prevent massive drop downs for related fields when the related model has lots of items, I'd like to add such fields automatically to raw_id_fields.
I've managed to make them read only by implementing the following get_readonly_fields method in the base class that all my ModelAdmin classes inherit:
MODELS_WITH_TOO_MANY_INSTANCES_FOR_ADMIN_SELECT = [
'auth.User',
# ...
}
class ModelAdmin(admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
explicit_readonly_fields = super(ModelAdmin, self).get_readonly_fields(request, obj)
automatic_readonly_fields = self.related_fields_with_too_many_instances()
return tuple(set(explicit_readonly_fields) | set(automatic_readonly_fields))
def related_fields_with_too_many_instances(self):
fields = []
for f in self.model._meta.fields:
# If the field isn't shown anyway, don't bother.
if self.fields and not f.name in self.fields:
continue
# If we made the field editable by id, that means we want to edit it, even if it's impractical
if f.name in self.raw_id_fields:
continue
# If the field is a ForeignKey to a blacklisted model, make it read only.
if isinstance(f, (django_models.ForeignKey, django_models.ManyToManyField)):
related_model = '%s.%s' % (f.rel.to._meta.app_label, f.rel.to._meta.object_name)
if related_model in MODELS_WITH_TOO_MANY_INSTANCES_FOR_ADMIN_SELECT:
fields.append(f.name)
return fields
However, power users occasionally complain that they can no longer edit these fields... which is why I'd like a get_raw_id_fields method that I could override.
Attachments (1)
Change History (12)
comment:1 by , 14 years ago
| Has patch: | set |
|---|
by , 14 years ago
| Attachment: | 17881-poc.patch added |
|---|
comment:2 by , 14 years ago
| Needs documentation: | set |
|---|---|
| Needs tests: | set |
| Triage Stage: | Unreviewed → Accepted |
comment:3 by , 14 years ago
| Cc: | added |
|---|
comment:4 by , 11 years ago
| Keywords: | raw_id_fields added |
|---|
comment:5 by , 11 years ago
| Keywords: | raw-id-fields added; raw_id_fields removed |
|---|
comment:6 by , 11 years ago
| Keywords: | raw_id_fields added; raw-id-fields removed |
|---|
comment:7 by , 9 years ago
I was wondering the other day why the default Django admin widget for related fields is a drop-down by default, instead of an autocomplete (as we can have with raw_id_field option), when my Django admin page was crashing down.
I understand that it's more convenient with a drop-down when you have few data, but there is a real risk for Django to crash / expose a lot of data through this feature, and that's not what we are used to with Django.
Usually, default choices in the whole framework are "safe".
@aaugustin, I guess you are not working on it right now, as this ticket is 4 years old.
Do you think it make sense to change this default behaviour, or it has too many impacts?
comment:8 by , 9 years ago
| Cc: | added |
|---|
comment:9 by , 9 years ago
The ticket for adding a more usable autocomplete widget is #14370. We might consider changing the default to that widget at some point, but it's not a decision to make lightly.
Feel free to work on this ticket if you like.
comment:11 by , 4 years ago
| Cc: | added |
|---|
I'm uploading an untested patch showing the idea.
It'd be nice if
get_raw_id_fieldsaccepted an optionalobjargument, but apparently, this information isn't available in theformfield_for_*methods. This needs more investigation.