Django 自动完成灯 Select2 小部件未出现

Posted

技术标签:

【中文标题】Django 自动完成灯 Select2 小部件未出现【英文标题】:Django autocomplete light Select2 widget not appearing 【发布时间】:2021-12-31 18:05:37 【问题描述】:

我一直在关注DAL tutorial,可以在以下位置访问json对象

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

所以我知道我的观点是有效的。除此之外,除了 ForignKey 的标准小部件之外,我似乎什么也得不到。通过查看 *** 中的以下帖子,我觉得一些静态文件或 javascript 库没有正确加载,但对于我来说,我无法弄清楚如何解决这个问题。

django-autocomplete-light template not rendering autocomplete widget

django-autocomplete-light displays empty dropdown in the form

以下是我认为与此问题有关的所有文件。如果我可以进一步澄清事情,请告诉我。

views.py(编辑添加的完整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>

我尝试使用教程中的确切% block content %,但没有不同的结果。任何帮助将不胜感激。

第二个问题:我对在 *** 上发帖还很陌生,想知道是否有人有一个很好的经验法则,即在发布问题之前应该花多少小时自己研究和尝试?

【问题讨论】:

您的开发工具控制台中是否出现任何错误?您应该删除模板底部添加表单集表单的整个 JS 部分,您没有表单集 删除了表单集脚本。在很多方面我还是新手。我正在使用 chrome,打开检查,然后单击选项卡控制台。当我加载页面时,该控制台中没有显示任何内容。 您是否在未加载 JS/CSS 的网络选项卡中收到任何 404? form.media 标记是否完全加载了 DAL 静态静态文件? 不,我没有。是否有可能我没有加载一些我需要的本地 select2.js。我使用了 collectstatic,可以在文件树中看到一些,但教程没有提及它 如果您运行开发服务器,则不需要运行 collectstatic。检查您是否在 INSTALLED_APPS 设置中添加了正确的应用程序,您可以添加呈现表单/模板的视图吗? 【参考方案1】:

您没有将表单类传递给视图,只是传递字段意味着您使用的表单只是一个自动生成的 ModelForm,没有您的自定义小部件

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

    ...

【讨论】:

这会显示小部件,但不会创建河流对象。河流对象具有名称、aw_id 和状态。我需要创建视图来创建河流吗 将 create_field 参数 url 更改为 river_name,小部件可以正常工作。但我无法创建新的 JournalEntry。单击保存没有任何作用,但我会在早上查看,非常感谢您的帮助 @TravisN.Miller 我怀疑这与表单上的字段有关,您应该将旧字段列表从视图复制到表单

以上是关于Django 自动完成灯 Select2 小部件未出现的主要内容,如果未能解决你的问题,请参考以下文章

Django 自动完成灯:未填充字段

在 django 中使用 JQuery 自动完成小部件

Angular UI select2 指令 - 以编程方式更新模型未反映在小部件上

多对多关系的 Select2 小部件

表单集中的 Select2MultipleWidget 未呈现

在获取数据时,对 Django 项目使用 Select2 自动完成功能不起作用