如何使用 Django 在表单中创建自动完成输入字段 [英] how to create a autocomplete input field in a form using Django

查看:36
本文介绍了如何使用 Django 在表单中创建自动完成输入字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Django 及其方式很陌生.我正在尝试为表单创建一个自动完成字段.我的代码如下

forms.py

from django 导入表单类 LeaveForm(forms.Form):离开列表 = (('临时休假', '临时休假'),('病假','病假'))from_email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'style': 'width: 400px'}))start_date = end_date = forms.CharField(widget=forms.TextInput(attrs={'type': 'date', 'style': 'width: 175px'}))leave_type = forms.ChoiceField(choices=leave_list, widget=forms.Select(attrs={'style': 'width: 400px'}))评论 = forms.CharField(required=True, widget=forms.Textarea(attrs={'style': 'width: 400px; height: 247px'}))def clean_from_email(self):数据 = self.cleaned_data['from_email']如果@testdomain.com"不在数据中:raise forms.ValidationError("必须是@testdomain.com")返回数据

我想要实现的是,当用户在 "From Email" 字段中键入单词时,我存储在外部数据库中的电子邮件列表应出现在自动完成列表选项中.>

models.py

from django.db 导入模型类 ListOfUsers(models.Model):emp_number = models.CharField(db_column='Emp_Number', primary_key=True, max_length=50, unique=True) # 字段名小写.name = models.CharField(db_column='Name', max_length=40) # 字段名小写.supervisor = models.CharField(db_column='Supervisor', max_length=40) # 字段名小写.email = models.CharField(db_column='Email', max_length=50, blank=False, null=False, unique=True) # 字段名小写.元类:管理 = 错误db_table = '用户列表'

知道如何做到这一点吗?

更新:

我开始使用 django-autocomplete-light,现在可以从自动完成网址获得回复.看起来像这样

{"results": [{"id": "user1@mydomain.com", "text": "user1@mydomain.com"}, {"id": "user2@mydomain.com", "text": "user2@mydomain.com"}, {"id": "user3@mydomain.com", "text": "user3@mydomain.com"}]}

views.py

class EmailAutocomplete(autocomplete.Select2ListView):def get_list(self):qs = ListOfUsers.objects.using('legacy')如果 self.q:qs = qs.filter(email__icontains=self.q).values_list('email', flat=True)返回 qs

我仍然不知道如何让这些数据出现在"from_email"

字段中

解决方案

我终于使用此处的说明使自动完成搜索工作了

https://github.com/xcash/bootstrap-autocomplete
https://bootstrap-autocomplete.readthedocs.io/en/latest/

使用起来非常简单,不需要在 settings.py 中安装任何应用程序,它适用于 bootstrap 3 和 bootstrap 4

还有很多其他可用的软件包,但这对我的需要来说很简单易行.

我将解释我使用的代码

page.html

{% 块脚本 %}<script src=https://cdn.rawgit.com/xcash/bootstrap-autocomplete/3de7ad37/dist/latest/bootstrap-autocomplete.js"</script><脚本>$('.basicAutoComplete').autoComplete({分钟长度:1});$('.dropdown-menu').css({'top': 'auto', 'left': 'auto'}){% 结束块 %}.....{% if field.name == "from_email";%}{% render_field field class="basicAutoComplete form-control";%}{% 别的 %}{% render_field 字段类=表单控件";%}{% 万一 %}

autoComplete 是为执行操作而调用的函数,minLength 指定执行提取操作之前文本的最小长度我添加了一个额外的 CSS 来修复自动完成下拉菜单,否则会很奇怪.

Jinja 渲染不断覆盖视图中的类定义,因此我添加了 if 检查.

urls.py

来自 .导入视图网址模式 = [...path('email_autocomplete/', views.email_autocomplete, name='email_autocomplete')]

将此行添加到 urls.py

forms.py

class LeaveForm(forms.Form):from_email = forms.EmailField(required=True, widget=forms.TextInput(属性={'style': '宽度:400px','class': 'basicAutoComplete','data-url': "/domain/email_autocomplete/";}))

以上是forms.py中输入框的代码.data-url 指向生成 JSON 结果的位置.

views.py

from django.http import HttpResponse, HttpResponseRedirect, JsonResponse从 .models 导入模型def email_autocomplete(请求):如果 request.GET.get('q'):q = request.GET['q']data = model.objects.using('legacy').filter(email__startswith=q).values_list('email',flat=True)json = 列表(数据)返回 JsonResponse(json, 安全=假)别的:HttpResponse(没有cookies")

这对我来说是最令人困惑的部分.GET 请求很容易理解,但是将数据从 model.objects 转换为 JSON 格式的对象需要一段时间.诀窍是使用

values_list('columnName',flat=True)

当从数据库中过滤数据时,然后使用list(data)转换为列表,最后使用JsonResponse将其转换为JSON.

希望这能帮助任何想要简单自动完成的人

I am pretty new to django and its ways. I am trying to create an autocomplete field for a form. My code is as below

forms.py

from django import forms

class LeaveForm(forms.Form):
    leave_list = (
        ('Casual Leave', 'Casual Leave'),
        ('Sick Leave', 'Sick Leave')
    )
    from_email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'style': 'width: 400px'}))
    start_date = end_date = forms.CharField(widget=forms.TextInput(attrs={'type': 'date', 'style': 'width: 175px'}))
    leave_type = forms.ChoiceField(choices=leave_list, widget=forms.Select(attrs={'style': 'width: 400px'}))
    comments = forms.CharField(required=True, widget=forms.Textarea(attrs={'style': 'width: 400px; height: 247px'}))

    def clean_from_email(self):
        data = self.cleaned_data['from_email']
        if "@testdomain.com" not in data:
            raise forms.ValidationError("Must be @testdomain.com")
        return data

What I want to achieve is that when an user types words into the "From Email" field the list of emails I have stored in an external DB should appear in the autocomplete list option.

models.py

from django.db import models


class ListOfUsers(models.Model):
    emp_number = models.CharField(db_column='Emp_Number', primary_key=True, max_length=50, unique=True)  # Field name made lowercase.
    name = models.CharField(db_column='Name', max_length=40)  # Field name made lowercase.
    supervisor = models.CharField(db_column='Supervisor', max_length=40)  # Field name made lowercase.
    email = models.CharField(db_column='Email', max_length=50, blank=False, null=False, unique=True)  # Field name made lowercase.


    class Meta:
        managed = False
        db_table = 'List of users'

Any idea how this can be done ?

Update :

I started messing around with django-autocomplete-light and now able to get a reply from the autocomplete url. It looks like this

{"results": [{"id": "user1@mydomain.com", "text": "user1@mydomain.com"}, {"id": "user2@mydomain.com", "text": "user2@mydomain.com"}, {"id": "user3@mydomain.com", "text": "user3@mydomain.com"}]}

views.py

class EmailAutocomplete(autocomplete.Select2ListView):
    def get_list(self):
        qs = ListOfUsers.objects.using('legacy')

        if self.q:
            qs = qs.filter(email__icontains=self.q).values_list('email', flat=True)

        return qs

I still do not know how to get this data to appear in the field "from_email"

解决方案

I finally got the autocomplete search working using the instructions found here

https://github.com/xcash/bootstrap-autocomplete
https://bootstrap-autocomplete.readthedocs.io/en/latest/

It is very simple to use and does not need to install any app in settings.py and it works for both bootstrap 3 and bootstrap 4

There are lot of other packages available but this was simple and easy for my need.

I am going to explain the code I used

page.html

{% block script %}
    <script src="https://cdn.rawgit.com/xcash/bootstrap-autocomplete/3de7ad37/dist/latest/bootstrap-autocomplete.js"></script>
    <script>
        $('.basicAutoComplete').autoComplete(
            {minLength: 1}
        );
        $('.dropdown-menu').css({'top': 'auto', 'left': 'auto'})

    </script>
{% endblock %}
.
.
.
.
.
{% if field.name == "from_email" %}
   {% render_field field class="basicAutoComplete form-control" %}
{% else %}
   {% render_field field class="form-control" %}
{% endif %}

autoComplete is the function called to perform the action and minLength specifies the minimum length of the text before performing the fetch action I added an extra CSS to fix the autocomplete dropdown otherwise it was weird.

The Jinja render kept overwriting the class definition from views so I added an if check for it.

urls.py

from . import views

urlpatterns = [
    .
    .
    .
    path('email_autocomplete/', views.email_autocomplete, name='email_autocomplete')
]

Added this line to urls.py

forms.py

class LeaveForm(forms.Form):
    from_email = forms.EmailField(required=True, widget=forms.TextInput(
        attrs={
            'style': 'width: 400px',
            'class': 'basicAutoComplete',
            'data-url': "/domain/email_autocomplete/"
        }))

The above is the code for the input field in forms.py. data-url points to where the JSON result would be generated.

views.py

from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from .models import model
        
def email_autocomplete(request):
    if request.GET.get('q'):
        q = request.GET['q']
        data = model.objects.using('legacy').filter(email__startswith=q).values_list('email',flat=True)
        json = list(data)
        return JsonResponse(json, safe=False)
    else:
        HttpResponse("No cookies")
            

This was the most confusing part for me. The GET request is easy to understand but it took a while to convert the data from model.objects into a JSON formatted object. The trick was to use

values_list('columnName',flat=True)

when filtering the data from the database, then converting to a list using list(data) and finally use JsonResponse to convert it to JSON.

Hope this will help any one who wants a simple autocomplete

这篇关于如何使用 Django 在表单中创建自动完成输入字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆