Search code examples
djangomodelchoicefieldmodelmultiplechoicefield

Django ModelMultipleChoiceField gives me a ProgrammingError


I would like to get your help because I'm getting an issue which is a little bit weird to my mind.

I'm using Django 1.11.16

I have in my forms.py file this class :

class PublicationStatForm(forms.Form):
    # publication_list = forms.ModelMultipleChoiceField(queryset=Publication.objects.all().order_by('pub_id'))
    publication_list = forms.ModelMultipleChoiceField(
        queryset=Publication.objects.all().order_by('pub_id'),
        label=_('Publication Choice'),
        widget=ModelSelect2Widget(
            model=Publication,
            search_fields=['pub_id__icontains', 'title__icontains'],
            attrs={'data-placeholder': "Please select publication(s)"}
        )
    )

    def __init__(self, *args, **kwargs):
        super(PublicationStatForm, self).__init__(*args, **kwargs)

Then, in my views.py file :

class StatsView(TemplateView):
    """ Create statistics pageview """
    template_name = 'freepub/stats.html'
    form_class = PublicationStatForm

    def get_context_data(self, **kwargs):
        subtitle = _("Statistics")
        context_data = super(StatsView, self).get_context_data(**kwargs)
        context_data['form'] = self.form_class()
        ...
        return context_data

And finally in my template, I just have :

<form class="date-form" method="GET">
   <div class="row">
      <div class="col-md-7">
        {{ form.publication_list }}
      </div>
   </div>
   <input id="submit-date-stats" type="submit" class="btn btn-default" name="SearchPublicationPeriod"
               value="{% trans 'Submit' %}"/><br/>
</form>

I don't understand why, when I have this line in my form it works :

# publication_list = forms.ModelMultipleChoiceField(queryset=Publication.objects.all().order_by('pub_id'))

But when I replace this line by this :

publication_list = forms.ModelMultipleChoiceField(
    queryset=Publication.objects.all().order_by('pub_id'),
    label=_('Publication Choice'),
    widget=ModelSelect2Widget(
        model=Publication,
        search_fields=['pub_id__icontains', 'title__icontains'],
        attrs={'data-placeholder': "Please select publication(s)"}
    )
)

I get this issue :

Exception Type: ProgrammingError at /freepub/stats
Exception Value: relation "select_cache" does not exist
LINE 1: SELECT COUNT(*) FROM "select_cache"
                             ^

Do you have any idea ?

EDIT : Add cache settings

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
    },
    # "default": {
    #     "BACKEND": "django_redis.cache.RedisCache",
    #     "LOCATION": "redis://127.0.0.1:6379/1",
    #     "OPTIONS": {
    #         "CLIENT_CLASS": "django_redis.client.DefaultClient",
    #     }
    # },
    'select': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'select_cache',
        'TIMEOUT': None,
    }
}

# Set the cache backend to select2
SELECT2_CACHE_BACKEND = 'select'

Solution

  • The issue is with your cache settings.

    Although you've set up a database cache backend, you need to run python manage.py createcachetable to actually create it in the database, similar to how you run migrate for regular model changes or additions - and is also why the error looks similar, which took me down the migrations route at first.

    The Django ProgrammingError exception is an extension of the base DatabaseError, so it always relates to something wrong in the database. (source )

    This wouldn't be the case if you use a redis or other KV store cache, as it will automatically insert it. Because the Django database cache uses a table in the same database, that table has to be created, per this section of the documentation.