1

I have been following the DAL tutorial and can access a json object at

http://127.0.0.1:8000/entry/river-autocomplete/?q=S

So i know my view is working. Beyond that I cannot seem to get anything but the standard widget for ForignKey. From looking at the following posts in stackoverflow I feel that some static files or javascript libraries are not loading properly but for the life of me I cannot figure out how to fix this.

django-autocomplete-light template not rendering autocomplete widget

django-autocomplete-light displays empty dropdown in the form

Below are all of the files that I think pertain to this issue. If I can clarify things any further please let me know.

views.py (edit added full views.py)

class CreateEntry(LoginRequiredMixin, generic.CreateView):
    fields = ('date', 'river', 'flow', 'description', 'public')
    model = JournalEntry


    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.user = self.request.user
        self.object.save()
        return super().form_valid(form)

    def get_success_url(self):
        return reverse_lazy('home')

#autocomplete view
class RiverAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        #User filtering code goes here
        if not self.request.user.is_authenticated:
            return River.objects.none()
        
        qs = River.objects.all()

        if self.q:
            qs = qs.filter(river_name__istartswith=self.q)
        return qs

settings.py

INSTALLED_APPS = [
    'dal',
    'dal_select2',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'journal',
    'accounts',
    'bootstrap5',
    'django.contrib.admin',
]

models.py

class River(models.Model):
    river_name = models.CharField(max_length=50)
    aw_id = models.CharField(max_length=20)
    state = models.CharField(max_length=5) 

    def __str__(self):
        return "{river}".format(river=self.river_name)


class JournalEntry(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateField()
    river = models.ForeignKey("River", on_delete=models.CASCADE)
    flow = models.FloatField()
    description = models.TextField(max_length=250)
    public = models.BooleanField(default=False)
    # picture = models.ImageField()

    def __str__(self):
        return "{river}--{date}".format(river=self.river, date=self.date)

forms.py

from django import forms
from . import models
from .widgets import FengyuanChenDatePickerInput
from dal import autocomplete

class JournalForm(forms.ModelForm):
    date = forms.DateField(input_formats=['%m/%d/%Y'], widget=FengyuanChenDatePickerInput())
    river = forms.ModelChoiceField(
        queryset=models.River.objects.all(),
        widget=autocomplete.ModelSelect2(url='journal:river-autocomplete'))

    class Meta:
        model = models.JournalEntry
        fields = ("__all__")

urls.py

from django.urls import path
from django.conf.urls import url

from . import views

app_name='journal'

urlpatterns = [
    ...
    ...
    #autocomplete view
    url(r'^river-autocomplete/$', views.RiverAutocomplete.as_view(model=River, create_field='name'), name='river-autocomplete'),
   
]

html

{% extends "base.html" %}
{% load static %}
{% block content %}

<div class="container">
    <h1>New Entry:</h1>

    
    <form method="post">
      
      {% csrf_token %}
        <h3>Date:</h3>
        {{ form.date}}
        <h3>River:</h3>
        {{ form.river }}
        <h3>Flow:</h3>
        {{ form.flow }}
        <h3>Description:</h3>
        {{ form.description }}
        <h4>Public:  {{ form.public }}</h4>

        
        <input type="submit" value="Save">
      

      
  </form>
</div>

{% endblock %}

{% block footer %}
<!-- DAL -->
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.js' %}"></script>

{{ form.media }}

<script>
  (function($) {
      $('#id_river').click(function() {
          var index = $('#id_inline_test_models-TOTAL_FORMS').val()
          var newTable = $('#id_inline_test_models-__prefix__-DELETE').parents('table').clone()
          newTable.find(':input').each(function() {
              for (attr of ['name', 'id'])
                  $(this).attr(
                      attr,
                      $(this).attr(attr).replace('__prefix__', index)
                  )
          })
          newTable.insertBefore($(this))
          $('#id_inline_test_models-TOTAL_FORMS').val(
              parseInt($('#id_inline_test_models-TOTAL_FORMS').val()) + 1
          )
          newTable.slideDown()
      })
  })($)
  </script>

<!-- Datepicker  -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.js" integrity="sha256-/7FLTdzP6CfC1VBAj/rsp3Rinuuu9leMRGd354hvk0k=" crossorigin="anonymous"></script>

<script>
  $(function () {
    $("#id_date").datepicker({
      format:'dd/mm/yyyy',
    });
  });
</script>

{% endblock %}

base.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title>American Whitewater Journal</title>
        

        <!-- Latest compiled and minified CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        
        
        <!-- jQuery -->
        <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
        


        <!-- Fengyuan Chen's Datepicker -->
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.css" integrity="sha256-b88RdwbRJEzRx95nCuuva+hO5ExvXXnpX+78h8DjyOE=" crossorigin="anonymous" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/datepicker/0.6.5/datepicker.min.js" integrity="sha256-/7FLTdzP6CfC1VBAj/rsp3Rinuuu9leMRGd354hvk0k=" crossorigin="anonymous"></script>
    </head>
    <body>
        <nav class="navbar navbar-expand-lg navbar-light mynav" style="background-color: #238c91" role="navigation" id="navbar">
      ...
      ...
      ...
    </nav>
        <div class="container">
            {% block content %}

            {% endblock %}
            {% block footer %}
            {% endblock %}
        </div>


    </body>
</html>

I have tried to use the exact {% block content %} that is in the tutorial without a differing result. Any help would be much appreciated.

Second question: I am pretty new to posting on stackoverflow and wonder if anybody has a good rule of thumb about how many hours one should spend researching and trying on your own before you post a question?

Travis N. Miller
  • 135
  • 1
  • 10
  • 1
    Do you get any errors in your devtools console? You should remove the whole section of JS at the bottom of your template where formset forms are being added, you don't have a formset – Iain Shelvington Nov 22 '21 at 03:57
  • Removed the formset script. I am still new at a lot of this. I am using chrome, open up inspect, and click the tab Console. Nothing shows up in that console when I load the page. – Travis N. Miller Nov 22 '21 at 04:46
  • 1
    Do you get any 404s in the network tab where the JS/CSS is not loading? Are the DAL static static files being loaded at all by the form.media tag? – Iain Shelvington Nov 22 '21 at 04:51
  • No I do not. Is it possible I am not loading some local select2.js i need to be. I used collectstatic and can see some in the file tree but the tutorial did not mention anything about it – Travis N. Miller Nov 22 '21 at 04:55
  • 1
    If you run the dev server you shouldn't need to run collectstatic. Check that you added the correct apps to the INSTALLED_APPS setting, can you add the view that renders the form/template? – Iain Shelvington Nov 22 '21 at 05:05

1 Answers1

1

You are not passing your form class to the view, just passing fields means that the form you are using is just an auto-generated ModelForm without your custom widget

class CreateEntry(LoginRequiredMixin, generic.CreateView):
    model = JournalEntry
    form_class = JournalForm

    ...
Iain Shelvington
  • 31,030
  • 3
  • 31
  • 50
  • This gets the widget to display but does not create a river object. The river objects have a name, an aw_id, and state. Do I need to create a view to create a river – Travis N. Miller Nov 22 '21 at 05:45
  • Changed the create_field parameter urls to river_name and the widget works as it should. But I cannot create a new JournalEntry. Clicking save does nothing but I will look at that in the morning Thank you so much for your help – Travis N. Miller Nov 22 '21 at 06:57
  • 1
    @TravisN.Miller I suspect it's to do with the fields on the form, you should copy the old field list from the view to the form – Iain Shelvington Nov 22 '21 at 07:08