django-autocomplete-light 的建议显示在下拉列表之外
django-autocomplete-light's suggestions displayed beyond the drop-down list
出于某种原因,来自 django-autocomplete-light 3.5.0
的建议显示在下拉列表的右侧(可见的窄蓝色矩形表示建议):
我能够反转小部件的 url 并获得正确的建议。一切正常但渲染 - 当我点击这个窄矩形时,正确的值出现在编辑框中。我收集了所有的静态文件。我正在研究 Linux 20.04 LTS、Chrome 83.0.4103.106、python 3.7.7、django 3.0.3、bootstrap 4.5.0 和 font-awesome 4.7。 0。这是我写的代码(设置除外)
forms.py
class OpinionForm(forms.ModelForm):
# user field is defined as hidden and disabled such that it couldn't be changed
user = forms.ModelChoiceField(
widget=forms.HiddenInput,
queryset=get_user_model().objects.all(),
disabled=True
)
# defining all the fields with autocomplete feature
country = forms.ModelChoiceField(
queryset=Country.objects.all(),
widget=autocomplete.ModelSelect2(url="country_autocomplete")
)
class Meta:
model = Opinion
fields = ("content",)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["country"].label = "Kraj"
self.fields["content"].label = "Treść"
models.py
class Country(models.Model):
name = models.CharField(max_length=200, null=False)
def __str__(self):
return self.name
class Opinion(models.Model):
user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
content = models.TextField()
created = models.DateTimeField(auto_now=True)
urls.py
urlpatterns = [
path("add_opinion", views.CreateOpinionView.as_view(), name="add_opinion"),
path("country-autocomplete/", CountryAutocomplete.as_view(create_field="name"),
]
views.py
class CountryAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Country.objects.none()
qs = Country.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
class CreateOpinionView(LoginRequiredMixin, CreateView):
form_class = OpinionForm
template_name = "opinions/create.html"
def get_initial(self):
"""
When our view is instantiating the form, it will pass the result of get_initial() as the 'initial'
argument and the POST data as the 'data' argument
:return:
"""
return {
"user": self.request.user.id
}
def form_valid(self, form):
"""
If a form is valid, CreateView will call form_valid.
If the form isn't valid, CreateView will re-render the template.
:param form:
:return:
"""
action = self.request.POST.get("action")
# when we want to save, we will call the original form_valid method
# the original method saves the new opinion
if action == "SAVE":
# save and redirect as usual
return super().form_valid(form)
return HttpResponseBadRequest()
create.html
{% extends "base.html" %}
{% load static %}
{% load crispy_forms_tags %}
{% block title %}Dodaj opinię{% endblock %}
{% block content %}
<div class="col-md-12">
<h1>Dodaj opinię</h1>
<form method="post">
{{ form | crispy }}
{% csrf_token %}
<button class="btn btn-primary" type="submit" name="action" value="SAVE">Zapisz</button>
</form>
</div>
{% endblock %}
{% block footer %}
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
{{ form.media }}
{% endblock %}
你的代码对我来说似乎工作正常,所以错误一定是在其他地方,可能是在你的 CSS.
中的某个地方
您的代码有两个错误导致它无法 运行 不过:
- on_delete 是自 Django 2.0 以来 ForeignKey 的必需参数。您确定您的版本是 运行 吗?
- user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
+ user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
- 我假设这是创建问题时的复制粘贴错误
- path("country-autocomplete/", CountryAutocomplete.as_view(create_field="name"),
+ path("country-autocomplete/", CountryAutocomplete.as_view(create_field="name"), name='country_autocomplete'),
以下是我的设置的其他详细信息,也许您会发现与您的不同的地方:
版本:
Django==3.0.3
django-autocomplete-light==3.5.0
django-crispy-forms==1.9.1
base.html
:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock title %}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>
<body>
{% block content %}
{% endblock %}
{% block footer %}
{% endblock %}
</body>
</html>
settings.py
:
# ...
INSTALLED_APPS = [
# ...
'dal',
'dal_select2',
'crispy_forms',
'yourappname'
]
# ...
# (everything else left at defaults)
出于某种原因,来自 django-autocomplete-light 3.5.0
的建议显示在下拉列表的右侧(可见的窄蓝色矩形表示建议):
forms.py
class OpinionForm(forms.ModelForm):
# user field is defined as hidden and disabled such that it couldn't be changed
user = forms.ModelChoiceField(
widget=forms.HiddenInput,
queryset=get_user_model().objects.all(),
disabled=True
)
# defining all the fields with autocomplete feature
country = forms.ModelChoiceField(
queryset=Country.objects.all(),
widget=autocomplete.ModelSelect2(url="country_autocomplete")
)
class Meta:
model = Opinion
fields = ("content",)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["country"].label = "Kraj"
self.fields["content"].label = "Treść"
models.py
class Country(models.Model):
name = models.CharField(max_length=200, null=False)
def __str__(self):
return self.name
class Opinion(models.Model):
user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
content = models.TextField()
created = models.DateTimeField(auto_now=True)
urls.py
urlpatterns = [
path("add_opinion", views.CreateOpinionView.as_view(), name="add_opinion"),
path("country-autocomplete/", CountryAutocomplete.as_view(create_field="name"),
]
views.py
class CountryAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Country.objects.none()
qs = Country.objects.all()
if self.q:
qs = qs.filter(name__istartswith=self.q)
return qs
class CreateOpinionView(LoginRequiredMixin, CreateView):
form_class = OpinionForm
template_name = "opinions/create.html"
def get_initial(self):
"""
When our view is instantiating the form, it will pass the result of get_initial() as the 'initial'
argument and the POST data as the 'data' argument
:return:
"""
return {
"user": self.request.user.id
}
def form_valid(self, form):
"""
If a form is valid, CreateView will call form_valid.
If the form isn't valid, CreateView will re-render the template.
:param form:
:return:
"""
action = self.request.POST.get("action")
# when we want to save, we will call the original form_valid method
# the original method saves the new opinion
if action == "SAVE":
# save and redirect as usual
return super().form_valid(form)
return HttpResponseBadRequest()
create.html
{% extends "base.html" %}
{% load static %}
{% load crispy_forms_tags %}
{% block title %}Dodaj opinię{% endblock %}
{% block content %}
<div class="col-md-12">
<h1>Dodaj opinię</h1>
<form method="post">
{{ form | crispy }}
{% csrf_token %}
<button class="btn btn-primary" type="submit" name="action" value="SAVE">Zapisz</button>
</form>
</div>
{% endblock %}
{% block footer %}
<script type="text/javascript" src="{% static "admin/js/vendor/jquery/jquery.js" %}"></script>
{{ form.media }}
{% endblock %}
你的代码对我来说似乎工作正常,所以错误一定是在其他地方,可能是在你的 CSS.
中的某个地方您的代码有两个错误导致它无法 运行 不过:
- on_delete 是自 Django 2.0 以来 ForeignKey 的必需参数。您确定您的版本是 运行 吗?
- user = models.ForeignKey(to=settings.AUTH_USER_MODEL)
+ user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
- 我假设这是创建问题时的复制粘贴错误
- path("country-autocomplete/", CountryAutocomplete.as_view(create_field="name"),
+ path("country-autocomplete/", CountryAutocomplete.as_view(create_field="name"), name='country_autocomplete'),
以下是我的设置的其他详细信息,也许您会发现与您的不同的地方:
版本:
Django==3.0.3
django-autocomplete-light==3.5.0
django-crispy-forms==1.9.1
base.html
:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock title %}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>
<body>
{% block content %}
{% endblock %}
{% block footer %}
{% endblock %}
</body>
</html>
settings.py
:
# ...
INSTALLED_APPS = [
# ...
'dal',
'dal_select2',
'crispy_forms',
'yourappname'
]
# ...
# (everything else left at defaults)