Home > Software design >  Django 4 seems to be caching my query. How can I turn it off?
Django 4 seems to be caching my query. How can I turn it off?

Time:06-25

The Issue

When I am updating a property (House) on the website.
Say for example, I update the State to Illinois -- the value does not show up in:

all_properties = models.Property.objects.all()

Even adding a new property (house) does not show up in the all_properties value when the UpdateView reloads.

It only shows up if I kill the Django server and restart it.

What can I do so that I have updated data show up on every load of the UpdateView?

Some context

I have a model with 20 attributes.
This is for a property-listing site (like Airbnb). So there are things like size, bedrooms, city, state, etc.

There needs to be an auto-complete functionality on the textboxes when I am editing these properties.

So for example, State is a text field in my form. When I am adding a 2nd house to my website, the State textbox should suggest values from the previous houses that I have in my system.

(Basically when I type C, it should show California if I have any houses with California already in the DB)

UpdateView

I am using an Update View to show my Property-Edit (House-Edit) page.
I need to pass in all these auto-complete fields inside this Update View so that I can add them to my text boxes.

The code looks like this:

class PropertyUpdateView(LoginRequiredMixin, UpdateView):
    context_object_name = 'property'
    model = models.Property
    form_class = forms.PropertyForm
    template_name = 'desertland/admin/property_update.html'

    extra_context = get_autocomplete_fields()

    def get_success_url(self):
        messages.success(self.request, 'The property was updated successfully.')
        return reverse('property_update', kwargs={'pk': self.object.id})

The extra_content is where I am passing my autocomplete fields.
The get_autocomplete_fields() method is like so:

def get_autocomplete_fields():
    ac_keys = ['state', 'city', 'county', 'zip_code', 'zoning', 'power', 'water_district', 'water', 'access', 'vetting']
    autocomplete_data = {}
    temp_list = {}

    all_properties = models.Property.objects.all()

    # Creating empty dictionaries for the autocomplete fields
    for key in ac_keys:
        temp_list[key] = []
        autocomplete_data[key] = []

    for property in all_properties:
        for key in ac_keys:
            # Creating a key if it does not exist
            if autocomplete_data.get(key) is None:
                autocomplete_data[key] = []

            val = getattr(property, key)

            # Creating an array of distinct values from the property
            if val and val not in temp_list[key]:
                temp_list[key].append(val)
                autocomplete_data[key].append({'value': val, 'label': val})

    return {'autocomplete_data': autocomplete_data}

This function works correctly and generates the Dictionary correctly.

My DB Model looks like this:

class Property(models.Model):
    id = models.AutoField(primary_key=True)
    slug = models.SlugField(unique=True, db_index=True)
    name = models.TextField(null=False, blank=False)
    ... more attributes ...

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Property, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("property_update", kwargs={'id': self.pk})

Some further debugging since I posted this question:

  1. The value is updated in the DB immediately.
  2. The updated values are shown if I access them via the ListView or the UpdateView. (i.e. it shows up in the input fields or my table).
  3. It is only reflected via the models.Property.objects.all() if I restart the Django server.
  4. If I create a new object, the count stays the same inside of the models.Property.objects.all() method. (i.e. even new objects are not reflected even though they are persisted in the DB).
  5. There is no caching framework active.
  6. TIMEOUT=0 in my settings.py has no effect.

CodePudding user response:

It doesn't show up, because you populate them when class is initialized.

class PropertyUpdateView(LoginRequiredMixin, UpdateView):
    context_object_name = 'property'
    model = models.Property
    form_class = forms.PropertyForm
    template_name = 'desertland/admin/property_update.html'

    # Here is the issue. extra_context is a static variable and 
    # get_autocomplete_fields() is called when class is initialized,
    # which in your case means when you start the server.
    extra_context = get_autocomplete_fields()

You have to move this extra context to get_context_data() method.

class PropertyUpdateView(LoginRequiredMixin, UpdateView):
    context_object_name = 'property'
    model = models.Property
    form_class = forms.PropertyForm
    template_name = 'desertland/admin/property_update.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['autocomplete_properties'] = get_autocomplete_fields()
        return context

    extra_context = get_autocomplete_fields()

Here is documentation on adding extra context.

  • Related