Scalable Widget for Rendering Foreign Keys in Django Admin - python

Is there a widget for rendering a foreign key field in Django admin that can scale to handle an arbitrarily large table and provide a user-friendly interface for looking up a FK?
The default widget in Django 1.3 is a select box that lists every record in the referenced table. For tables containing hundreds of thousands of records...this basically crashes the server. I see there's a ref_id_fields ModelAdmin option, for rendering the field as a simple text box, but that strikes me as a pretty un-user-friendly workaround since it expects the user to know the exact ID for the record they want to reference.
I'm surprised no solution for this is already builtin, but Googling only found me one project implementing a jQuery-powered autocomplete widget. Are there any other solutions for this problem?

are you getting all the static files? raw_id_fields come with an ajax widget, which puts a little magnifying glass next to the text box with the input widget. clicking brings up a popup with a changelist (including e.g. search) that you can use to find the id. (and automatically insert by clicking the entry)
see screenshot (first google image search)

There are several more auto-complete apps for Django: http://djangopackages.com/grids/g/auto-complete/

Related

Is it possible to customize a specific double click behavior on Django admin?

Bear with my in this moment of confusion.
I have a project for a small clinic, which will be made using Python+Django.
It's a "very simple" application: they want their patients list and their consults list.
I will do this in Django, using only the admin interface(because it's the only way I know). It will be separated in two modules, one for patients, other for consults.
Here is my question: When the user adds a new consult on the django admin interface, is it possible for him to double click the name of that patient in the form input to open a window with the patient page? (the django admin patient module page)
Look at the screen-shot above, it's a selector with the lists of all patients(this is one of the inputs when inserting a new consult), the NORMAL BEHAVIOR of this is when you click someone, it highlights, when its highlighted and you click the arrow, it passes to the other site, or when you DOUBLE CLICK someone, it passes to the other side too.
What I wanted to do, is when you double click someone, it opened the patient window. Is this possible?
Thanks in advance.

Django editable dropdown field [duplicate]

We have some models that are have a user as a foreign key. But with about 25000 users in our system, it's a bit daunting to find the one we need.
Is there a solution out there that's better than the select box? Maybe an autocomplete so we can start typing the user name / address? Or just a search box? When switching the related user for these objects, it's getting harder and harder with 25000 unsorted users.
Even just setting it to sort the users by username would be helpful.
I had this problem and my conclusion was to use an autocomplete field instead. It works pretty well in most cases. The only problem is when you have a lot of entries that are mostly the same. For example, in your case, if you type Robert for the name and there's a few hundred Robert entries in the list...
UPDATE
As mentions in shuckc's answer, Django 2.0+ admin as now autocomplete built in.
For older Django or to use outside of the admin (old answer)
There are many apps that add autocomplete to the Django admin:
django-autocomplete-light
django-extensions (ForeignKeyAutocompleteAdmin)
django-autocomplete (on google code)
django-ajax-selects
django-admin-autocomplete
django-autocomplete (tyrion)
My preferred one is the last one. It's well written, it can be used with the admin and outside of the admin, it works with ManyToManyFields, ForeignKeyFields, CharFields, etc.
I did a fork of this project for my client that adds some niceties like a lookup (loupe) button like the ForeignKeyRawIdWidget.
Django 2.0 admin has autocomplete built in, just set the autocomplete_fields field on the ModelAdmin class. e.g.
class QuestionAdmin(admin.ModelAdmin):
ordering = ['date_created']
search_fields = ['question_text']
class ChoiceAdmin(admin.ModelAdmin):
autocomplete_fields = ['question']
The simplest out-of-the-box solution is to add the field to your ModelAdmin's raw_id_fields -- then you'll get a pop-up window in which you can use the built-in searching/filtering and pagination control's to find and select the object you're after.
If you really want autocomplete, the other answers give a you reasonable starting point.
You can use the ForeignKeyRawIdWidget from django.contrib.admin.widgets. It renders FK relations as an input with a small button along-side which presents a searchable pop up.
There is an app for that (django-autocomplete).

Django modelform: Create new related object

I've been searching stack overflow and google for a solution for over an hour now, and I can't seem to find something that, in my opinion, should be easy to obtain (as it's a common use case).
I've checked this thread, and a few others, but I haven't been able to find a real, easy solution:
Django modelform: is inline adding related model possible?
Anyway, say I have a model with three related entities, two foreign keys and a many-to-many related class. Now, I have a ModelForm which displays these in comboboxes and lists, but what I need is that "+" button next to these elements (as seen in the admin interface).
I want the plus to take me to a new form, for that particular entity, allow me to submit the new information, create the database entry, take me back to my original form and have the newly added entity selected in the combobox. I'm really hoping the django ModelForm Meta class has an attribute that I can't seem to find which enables exactly this.
This isn't really a django question.
This has to do with presentation of a particular widget in an html document, and that is governed by either the HTML markup, CSS, or javascript.
Django is a server side application and is primarily responsible for creating a valid http response and receiving a valid http request (of course, there is a lot that happens in the interim and that is why django is so big) but it's not a "one toolkit to kill them all" app.
I think you want to look at bootstrap: http://getbootstrap.com/
Jquery UI: http://jqueryui.com/
Or some combination of the two.
You can also just mark up the document yourself with a stock img or something.
However, if you want to do it exactly how the admin does it, just go into django.contrib.admin and examin the code to figure out how the django developers did it. I believe they are just using Jquery UI and some manual markup to accomplish that.

Web2Py - Custom File Upload Form with Crud

I'm creating a custom file upload form in Web2Py, and was hoping some more experienced users could help me solve a few issues. Basically, the database ("t_file") is defined in "db_wizard.py", and in the controller, I'm calling crud.create(db.t_file, next=URL('upload')); a form is added in the html file with {{form}}.
There are about a dozen fields created, two of which are selectors, one is a file upload/browse field, and the rest are input boxes. I would like to make the following changes:
-Currently, the selectors default to an empty option. They are defined in the DB file like this:
Field('f_data_real_or_fabricated_bool', 'list:string', requires=IS_IN_SET(['T','F']),
label=T('Real or Fabricated')),
However. when displayed, the first option is empty, and the two other options are below the empty option. Is there a way to get rid of the empty option?
-The regular text input boxes, the selector boxes, and the filename input box are different widths. What is the best way to make them the same width? I've been trying all sorts of things with the CSS, but can't seem to get it.
-Is there a way to use expandable text boxes for some of text input areas?
-I would like the first several input fields to be required, and the rest to be optional. The mandatory fields should appear on the upload page by default, and the rest optional fields should only appear when an "advanced fields" (something along those lines) checkbox is checked. What is the best way to do this?
Can the above changes be made by sticking with the crud.create or crud.* methods, without designing custom forms?
I think you should attack one thing at the time and, for each one, try paste some code that helps a lot. I try to answer the last question: I think you won't be able to do that with crud interface without change the inner code (DO NOT DO THAT!). With SQLFORM, you can, altering CSS on Fields. But, the best and more controllable, although more hard work, is creating custom forms.

Improving Performance of Django ForeignKey Fields in Admin

By default, Django's admin renders ForeignKey fields in admin as a select field, listing every record in the foreign table as an option. In one admin-accessible model, I'm referencing the User model as a ForeignKey, and since I have thousands of users Django is populating the select with thousands of options. This is causing the admin page to load incredibly slowly, and the select is not very useful since it can take a while to scroll through thousands of options to find the one you want.
What's the best way to change the rendering of this field in order to improve page load and usability? I'd like the select field to be replaced with some sort of button to launch a search form popup, or a text field that searches keywords via Ajax to find the Id for the specific User they want to associate. Does admin have anything like this builtin, or would I have to write this from scratch?
Add raw_id_fields to your model to only show the ID instead of a dropdown.
You're right, Cerin, the cause of the slowdown is because Django is populating the <select> element with too many options. You might want to use an autocomplete element instead.
Interestingly, Django 2.0 has introduced a new feature on the admin site, called autocomplete_fields, which I think you will find useful in this case. It uses AJAX.
class ExampleAdmin(models.ModelAdmin):
autocomplete_fields = ['example_field_user']
You can use one of the few autocomplete apps for Django. Check them at Django Packages.
There's also django-extensions that have ForeignKeyAutocompleteAdmin that fit your needs pretty well.
Another option is to add readonly_fields instead of raw_id_fields

Categories

Resources