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:
- The value is updated in the DB immediately.
- The updated values are shown if I access them via the
ListView
or theUpdateView
. (i.e. it shows up in the input fields or my table). - It is only reflected via the
models.Property.objects.all()
if I restart the Django server. - 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). - There is no caching framework active.
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.