Last year, my wife started open a shopping service for entrusted goods. When she started getting overwhelmed managing the orders, I built a simple website for her, so she can manage the products and the orders through the website. By the way, I was using Django and Django Admin to build the website.
Few days ago, she asked me to add the autocomplete function when searching the product on the create order page. She asked for it because she already had a lot of products. Until now, she has around 190 products to manage. You can imagine that it would be difficult to choose a product when using mobile browser.
By the way, the table structure between the order and the product is many to many. So, I am using admin.TabularInline on the create order page. After googling some materials, I found the library to add the autocomplete function easily to Django Admin form.
Django Ajax Selects
From the github page of Django Ajax Selects, it is very easy to add autocomplete function. We just have to install the library, add the library to INSTALLED_APPS on settings.py, create lookup function, create custom form, and register the form to the admin. We can see the screenshot below after implement the function.
Now, she can directly type the product and choose the product she want. But, I realized that there is no add and edit button for the product. When you use Django Admin admin.TabularInline, you can find some buttons beside the select form. When you click that button, it will show the pop up for add new item or edit the existing item.
Add and Edit Button
After reading the documentation, it only shows how to implement the add button. Because I am using the tabular line, you just have to add AjaxSelectAdminTabularInline to the inline class.
from .models import OrderProduct
from ajax_select.admin import AjaxSelectAdminTabularInline
...
class OrderProductInline(AjaxSelectAdminTabularInline):
model = OrderProduct
Then you will see the add button beside the form.
If we click the add button, it will pop up the add product page. But, where is the edit button? Because when we choose the product, it only show the trash button to remove the item.
From the documentation, I cannot find any resource to add the edit button. But, after reading it again, I think I can create the custom return for the format_item_display function inside the lookups.py file. Previously, it only return the item name.
def format_item_display(self, item):
return u"<span class='tag'>%s</span>" % item.name
Then I tried to modify the return template.
def format_item_display(self, item): return """ <span class='product'>{}</span> <a id='change_id_order_product_{}' class='related-widget-wrapper-link change-related' data-href-template='/admin/products/product/__fk__/change/?_to_field=id&_popup=1' href='/admin/products/product/{}/change/?_to_field=id&_popup=1' > <img src="/static/admin/img/icon-changelink.svg" alt="Change"> </a>""".format(item.name, item.id, item.id)
I just clone the behaviour from another form that has a button to add and edit function. Then, voila, we can see the edit button now.
Do not forget to add the id, so the pop up can be closed automatically after we submitted the edit button.
Conclusion
You can see that it is very easy to add autocomplete function to the select form in Django Admin. Actually I found another library, Django Autocomplete Light. It is a great library, but after reading the documentation, I chose Django Ajax Selects, because it was easier for me to implement the autocomplete function for inline form.