Как создать автозаполнение поля ввода в форме, используя Django - PullRequest
0 голосов
/ 17 мая 2018

Я довольно новичок в Джанго и его способах.Я пытаюсь создать поле автозаполнения для формы.Мой код такой, как показано ниже

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

Чего я хочу добиться, так это когда пользователь вводит слова в поле "From Email" спискаэлектронные письма, хранящиеся во внешней БД, должны отображаться в параметре списка автозаполнения.

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'

Есть идеи, как это можно сделать?

Обновление:

Я начал возиться с django-autocomplete-light и теперь смог получить ответ от URL автозаполнения.Выглядит это так

{"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

Я до сих пор не знаю, как заставить эти данные появляться в поле "from_email"

1 Ответ

0 голосов
/ 31 мая 2018

Я наконец-то запустил поиск автозаполнения, используя приведенные здесь инструкции

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

Он очень прост в использовании и не требует установки какого-либо приложения в settings.py, и он работает как для начальной загрузки 3, так и для начальной загрузки 4

Есть много других доступных пакетов, но это былопросто и легко для моих нужд.

Я собираюсь объяснить код, который я использовал

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функция, вызываемая для выполнения действия, и minLength определяет минимальную длину текста перед выполнением действия извлечения. Я добавил дополнительный CSS, чтобы исправить выпадающий список автозаполнения, в противном случае это было странно.

Визуализация Jinja продолжала перезаписыватьопределение класса из представлений, поэтому я добавил проверку if для него.

urls.py

from . import views

urlpatterns = [
    .
    .
    .
    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(
        attrs={
            'style': 'width: 400px',
            'class': 'basicAutoComplete',
            'data-url': "/domain/email_autocomplete/"
        }))

Выше приведен код для вводаполе в forms.py.URL-адрес данных указывает на то, где будет сгенерирован результат JSON.

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")

Это была самая запутанная часть для меня.Запрос GET прост для понимания, но для преобразования данных из model.objects в форматированный объект JSON потребовалось некоторое время.Хитрость заключалась в том, чтобы использовать

values_list('columnName',flat=True)

при фильтрации данных из базы данных, затем преобразовывать в список с помощью list(data) и, наконец, использовать JsonResponse для преобразования его в JSON.

Hopeэто поможет любому, кто хочет простое автозаполнение

...