4

I have a simple model:

class Sheker(models.Model):
    name = models.CharField(max_length=90)
    display_name = models.CharField(max_length=90, null=True)
    search_name = models.CharField(max_length=90, null=True)

    def __unicode__(self):
        return self.search_name


class Sod(models.Model):
    name = models.CharField(null=False, blank=False, max_length=100)
    sheker = models.ManyToManyField(Sheker, blank=True, name='sheker')

With a simple form:

from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple
from rosh.models import *

class SodForm(forms.ModelForm):
    sheker = forms.ModelMultipleChoiceField(
        queryset=Sheker.objects.all(),
        widget=FilteredSelectMultiple("sheker", is_stacked=False),
        required=False
    )

The model Sheker have more then 12K rows in the db (postgres with geo extensions)- and the problem is that it makes the form to load super slow = more then 5 seconds to load the html.

Is the problem is queryset=Sheker.objects.all()? How can I make it load faster/cache it or something else to load the page fast (as normal web page).

What is the best practice for such issue?

enter image description here

  • 2
    While querying for 12K objects can take a while (what do you mean by "super slow" exactly?) I would guess, that the major problem is rendering the 12K rows on the html template. Have you thought about the user experience at all? How does the user select from a list of 12K options? Are there other alternatives to your approach? – skoll Sep 05 '16 at 10:25
  • Oh, have you look into the code at all? The widget FilteredSelectMultiple from django admin taking care of it. I will add some screenshot. –  Sep 05 '16 at 10:47
  • Even if you use FliteredSelectMultiple widget, presenting the user 12K options to choose from is not very user friendly. If you could filter the list somehow (maybe ask the user some questions before fetching the list) you can make it more user friendly and speed up the page. – skoll Sep 05 '16 at 10:54

2 Answers2

2

You can use Cache database to hold the values if the query is performed for more often, then this would be a good solution.

you can cache the [whole view] (https://docs.djangoproject.com/en/dev/topics/cache/#the-per-view-cache) this if the page is used often or else just the query whichever seems appropriate for your application.

You can cache the query set results something like this:

from django.core.cache import cache
from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple
from rosh.models import *

class SodForm(forms.ModelForm):

   # Check if the result is already cached
   sheker_results = cache.get('sheker_results'): # Returns None if not cached earlier

   # If the result is None, then query the database and set the cache
   if sheker_results is None:
       sheker_results = Sheker.objects.all()
       cahce.set('sheker_results',  sheker_results)

    sheker = forms.ModelMultipleChoiceField(
        queryset= sheker_results,
        widget=FilteredSelectMultiple("sheker", is_stacked=False),
        required=False
    )

This post describes about caching in django.

Community
  • 1
  • 1
kt14
  • 838
  • 15
  • 25
0

May be you can set field autocompletion in form, it will relieve the form and the page is loaded quickly, and the field will load the data from the database using only.

And then accelerate postgresql

dd42
  • 138
  • 3