2016-10-18 try a more simple approach with jquery-ui autocomplete widget

../../../_images/autocomplete_widget.png

Create a projects application

python manage.py startapp projects
|   ajax_selects_singers_db
|   manage.py
|   tree.txt
|
+---projects
|   |   admin.py
|   |   apps.py
|   |   models.py
|   |   tests.py
|   |   views.py
|   |   __init__.py
|   |
|   \---migrations
|           __init__.py

Add the Django model Project

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/python
# -*- coding: utf8 -*-
"""The project's models.

"""
from __future__ import unicode_literals
from django.utils.encoding import python_2_unicode_compatible

from django.db import models
from django.core.urlresolvers import reverse

# https://docs.djangoproject.com/en/dev/ref/contrib/auth/#user-model
from django.contrib.auth.models import User



@python_2_unicode_compatible
class Project(models.Model):
    """A project with a title and a champion which is the foreign key to the 
       auth user.

    Documentation
    =============

    - http://guiqinqian.blogspot.fr/2012/01/using-jquery-auto-complete-in-django.html

    """
    title = models.CharField(max_length=200)
    champion = models.ForeignKey(User)

    def __str__(self):
        return "{} {}".format(self.title, self.champion)

    def get_absolute_url(self):
        """
        https://docs.djangoproject.com/en/dev/ref/class-based-views/generic-editing/
        """
        return reverse('projects:project_update',
                       kwargs={'pk': self.pk})

Add the project in the INSTALLED_APPS

    # # https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig
    'singers.apps.SingersConfig',
    # http://guiqinqian.blogspot.fr/2012/01/using-jquery-auto-complete-in-django.html
    'projects.apps.ProjectsConfig'
]
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
"""
Django settings for projet_ajax project.

Generated by 'django-admin startproject' using Django 1.10.2.

For more information on this file, see
https://docs.djangoproject.com/en/1.10/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.10/ref/settings/
"""

import os
import logging

from os.path import (join,
                     basename,
                     dirname)

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
DJANGO_ROOT = BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Site name ('projet_ajax')
SITE_NAME = basename(DJANGO_ROOT)
# Absolute filesystem path to the top-level project folder:
PROJECT_ROOT=dirname(DJANGO_ROOT)

logging.info("DJANGO_ROOT={} SITE_NAME={} PROJECT_ROOT={}".format(
    DJANGO_ROOT,
    SITE_NAME,
    PROJECT_ROOT,
))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'q#e(dtsmq9^!(%9*un6tuq5v)2!@00ftgk$!@h1*(e0iwo@=cc'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

# for the debug toolbar
INTERNAL_IPS = '127.0.0.1'

DEBUG_TOOLBAR_PANELS = [
    'debug_toolbar.panels.versions.VersionsPanel',
    'debug_toolbar.panels.timer.TimerPanel',
    'debug_toolbar.panels.settings.SettingsPanel',
    'debug_toolbar.panels.headers.HeadersPanel',
    'debug_toolbar.panels.request.RequestPanel',
    'debug_toolbar.panels.sql.SQLPanel',
    'debug_toolbar.panels.staticfiles.StaticFilesPanel',
    'debug_toolbar.panels.templates.TemplatesPanel',
    'debug_toolbar.panels.cache.CachePanel',
    'debug_toolbar.panels.signals.SignalsPanel',
    'debug_toolbar.panels.logging.LoggingPanel',
    'debug_toolbar.panels.redirects.RedirectsPanel',
]


ALLOWED_HOSTS = []


# Applications definition
INSTALLED_APPS = [
    'dal',
    'dal_select2',

    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # https://django-extensions.readthedocs.org/en/latest
    'django_extensions',

    # http://django-ajax-selects.readthedocs.io/en/latest/index.html
    'ajax_select',
    # http://django-crispy-forms.readthedocs.io/en/latest/install.html#installing-django-crispy-forms
    'crispy_forms',
    # https://github.com/jazzband/django-debug-toolbar
    # 'debug_toolbar',

    # # https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig
    'singers.apps.SingersConfig',
    # http://guiqinqian.blogspot.fr/2012/01/using-jquery-auto-complete-in-django.html
    'projects.apps.ProjectsConfig'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

    # 'debug_toolbar.middleware.DebugToolbarMiddleware'
]


ROOT_URLCONF = 'projet_ajax.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'projet_ajax.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR,'ajax_selects_singers_db')
    }
}

# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/dev/howto/static-files/
STATIC_ROOT = join(PROJECT_ROOT, 'staticfiles')
# STATIC_ROOT="C:/projects_id3/P5N001/XLOG5R372_id3_intranet/trunk/django-www/staticfiles"
# Static files (CSS, JavaScript, Images)
# http://www.marinamele.com/taskbuster-django-tutorial/create-home-page-with-tdd-staticfiles-templates-settings
# https://docs.djangoproject.com/en/dev/howto/static-files/
# http://whitenoise.evans.io/en/latest/django.html#runserver-nostatic
STATIC_URL = '/static/'
# https://docs.djangoproject.com/en/dev/howto/static-files/
# les répertoires ou sont sockés les fichiers statiques en developpement
STATICFILES_DIRS = [
    join(DJANGO_ROOT, 'static'),
]

AJAX_LOOKUP_CHANNELS = {
    # simplest way, automatically construct a search channel by passing a dict
    'label': {'model': 'singers.label'
            , 'search_field': 'name'},

    # Custom channels are specified with a tuple
    # channel: ( module.where_lookup_is, ClassNameOfLookup )
    # 'person': ('singers.lookups', 'PersonLookup'),
    # 'group': ('singers.lookups', 'GroupLookup'),
    # 'song': ('singers.lookups', 'SongLookup'),
}

# voir https://github.com/jordij/bctt.nz/blob/master/ttwellington/settings/base.py
MEDIA_ROOT = join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

makemigrations

python manage.py makemigrations projects
Migrations for 'projects':
  projects\migrations\0001_initial.py:
    - Create model Project
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-10-18 10:45
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Project',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=200)),
                ('champion', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
            ],
        ),
    ]

sqlmigrate

python manage.py sqlmigrate projects
(ajax_django_35) C:\projects_id3\django_ajax_select\projet_ajax>python manage.py sqlmigrate projects 0001
BEGIN;
--
-- Create model Project
--
CREATE TABLE "projects_project" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(200) NOT NULL, "champion_id" integer NOT NULL REFERENCES "auth_user" ("id"));
CREATE INDEX "projects_project_68b9a77a" ON "projects_project" ("champion_id");
COMMIT;

migrate

python manage.py migrate projects
Operations to perform:
  Apply all migrations: projects
Running migrations:
  Applying projects.0001_initial... OK

Create the projects/forms.py file and add 2 forms

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/python
# -*- coding: utf8 -*-
"""The project's forms.

"""

from django import forms

from .models import Project

class ProjectChampionForm(forms.ModelForm):
    """The champion project form"""
    champions_choice_list = forms.CharField(max_length=100,
                                       help_text='type username or email')

    class Meta:
        model = Project
        fields = ('title',
                  'champions_choice_list', 'champion',)

    def __init__(self, *args, **kwargs):
        super(ProjectChampionForm, self).__init__(*args, **kwargs)
        self.fields['champions_choice_list'].label = "Update the champion"
        self.fields['champion'].widget = forms.HiddenInput()

Create the projects/urls.py file and add the champion auto complete URL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# -*- coding: utf-8 -*-

from django.conf.urls import url


from .views_json import (ApiEACGetProjectsJSONView,
                        ApiEACGetchampionsJSONView)

from .views_django_autocomplete_light import (ApiUserDjangoAutocompleteLight,
                                              ProjectDjangoAutoCompleteUpdateView,
                                              ProjectAutocompleteView)

from .views import (ProjectUpdateView,
                    ProjectUpdateViewEasyAutoComplete,
                    ProjectUpdateViewJQueryUIAutoComplete)


urlpatterns = [
     url(r'^project/(?P<pk>\d+)/update/$',
         ProjectUpdateView.as_view(),
         name='project_update'),

    url(r'^project/(?P<pk>\d+)/updateeasy/$',
        ProjectUpdateViewEasyAutoComplete.as_view(),
        name='project_update_easy'),

    url(r'^project/(?P<pk>\d+)/update_jquery_ui/$',
        ProjectUpdateViewJQueryUIAutoComplete.as_view(),
        name='project_update_jquery_ui'),

    url(r'^project/(?P<pk>\d+)/update_django_autocomplete/$',
        ProjectDjangoAutoCompleteUpdateView.as_view(),
        name='project_update_django_autocomplete'),

     # calls by jquery EasyAutocomplete
     # http://127.0.0.1:8004/projects/api_get_champions/?term=a
     url(r'^api_get_champions/$',
         ApiEACGetchampionsJSONView.as_view(),
         name='api_get_champions'),

    # calls by jquery EasyAutocomplete (EAC)
    # http://127.0.0.1:8004/projects/api_get_projects/?term=a
    url(r'^apis_get_projects/$',
        ApiEACGetProjectsJSONView.as_view(),
        name='api_get_projects'),

     # calling example:
     # http://127.0.0.1:8004/projects/project_autocomplete/?q=a
     url(
        r'^project_autocomplete/$',
        ProjectAutocompleteView.as_view(),
        name='project_autocomplete',
     ),

    url(r'^api/get_users/$',
        ApiUserDjangoAutocompleteLight.as_view(),
        name='api_get_users'),
]

Add the projects.urls file to the root urls.py

url(r'^projects/', include('projects.urls', namespace='projects')),
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/python
# -*- coding: utf8 -*-
"""projet_ajax URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""

from django.conf import settings
from django.conf.urls import (include,
                              url)

from django.contrib import admin

from ajax_select import urls as ajax_select_urls
from singers import views


urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^search',
        view=views.search_form,
        name='search_form'),
    url(r'^admin/lookups/', include(ajax_select_urls)),

    url(r'^projects/', include('projects.urls', namespace='projects')),
    url(r'^singers/', include('singers.urls', namespace='singers')),
]


if settings.DEBUG:
    from django.contrib.staticfiles.urls import staticfiles_urlpatterns
    from django.conf.urls.static import static
    urlpatterns += staticfiles_urlpatterns()
    # voir p.405 "Django By Example"
    # https://docs.djangoproject.com/en/dev/howto/static-files/#serving-files-uploaded-by-a-user-during-development
    urlpatterns += static(settings.MEDIA_URL ,
                          document_root=settings.MEDIA_ROOT)

    import debug_toolbar
    urlpatterns += [
        url(r'^__debug__/', include(debug_toolbar.urls)),
    ]

Add the ProjectUpdateView

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100


import logging

from django.core.urlresolvers import reverse

from django.views.generic.edit import UpdateView
from django.http import HttpResponseRedirect


from .models import Project
from .forms import ProjectChampionForm


# Get an instance of a logger
logger = logging.getLogger(__name__)


class ProjectUpdateView(UpdateView):
    """
            url(r'^projects/project/(?P<pk>\d+)/update/$', ProjctUpdate.as_view(), name='project_update'),

    Documentation:

    - http://ccbv.co.uk/projects/Django/1.10/django.views.generic.edit/UpdateView/

    """
    model = Project
    form_class = ProjectChampionForm
    context_object_name = 'project'
    template_name = 'projects/project/update_easy_simple.html'

    def get_object(self, queryset=None):
        """Pour mémoriser self.demande_article"""
        self.object = super(ProjectUpdateView, self).get_object(queryset)
        return self.object

    def post(self, request, *args, **kwargs):
        logger.warning("Hello from ProjectUpdateView !")
        if "cancel" in request.POST:
            url = self.get_success_url()
            return HttpResponseRedirect(url)
        else:
            return super(ProjectUpdateView, self).post(request, *args, **kwargs)




class ProjectUpdateViewEasyAutoComplete(UpdateView):
    """Update thye view with the jQuery EasyAutocomplete plugin.

    Documentation:

    - http://ccbv.co.uk/projects/Django/1.10/django.views.generic.edit/UpdateView/

    """
    model = Project
    form_class = ProjectChampionForm
    context_object_name = 'project'
    template_name = 'projects/project/update_easyautocomplete.html'

    def get_object(self, queryset=None):
        """Pour mémoriser self.demande_article"""
        self.object = super(ProjectUpdateViewEasyAutoComplete, self).get_object(queryset)
        return self.object

    def post(self, request, *args, **kwargs):
        logger.warning("Hello from ProjectUpdateViewEasyAutoComplete !")
        if "cancel" in request.POST:
            url = reverse('projects:project_update_easy', kwargs={'pk': self.pk})
            return HttpResponseRedirect(url)
        else:
            return super(ProjectUpdateViewEasyAutoComplete, self).post(request, *args, **kwargs)


class ProjectUpdateViewJQueryUIAutoComplete(UpdateView):
    """Update the view with the jQuery UI Autocomplete plugin.

    Documentation:

    - http://ccbv.co.uk/projects/Django/1.10/django.views.generic.edit/UpdateView/

    """
    model = Project
    form_class = ProjectChampionForm
    context_object_name = 'project'
    template_name = 'projects/project/update_jquery_ui_autocomplete.html'

    def get_object(self, queryset=None):
        """Pour mémoriser self.demande_article"""
        self.object = super(ProjectUpdateViewJQueryUIAutoComplete, self).get_object(queryset)
        return self.object

    def post(self, request, *args, **kwargs):
        logger.warning("Hello from ProjectUpdateViewJQueryUIAutoComplete !")
        return super(ProjectUpdateViewJQueryUIAutoComplete, self).post(request, *args, **kwargs)




Create the templates/projects/project/update.html django template

This template file is used by the ProjectUpdateView.

../../../_images/jquery_ui.png
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
{% extends "base.html" %}
{% load static %}
{% load staticfiles %}


{# STYLE CSS #}
{% block stylesheet %}
    {{ block.super }}
    {# https://www.bootstrapcdn.com/ #}
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.csss">

    <style>
    {# https://jqueryui.com/autocomplete/#maxheight #}
    .ui-autocomplete {
        max-height: 100px;
        overflow-y: auto;
        /* prevent horizontal scrollbar */
        overflow-x: hidden;
    }
    * html .ui-autocomplete {
        height: 100px;
    }
    </style>

{% endblock  %}


{% block content %}

    <h1>Update of the project '(title:{{ project.title }} champion:{{ project.champion }}) </h1>
    <p></p>
    <p></p>
    {# https://docs.djangoproject.com/en/dev/topics/forms/ #}
    <form id="id_form_project_update" action="{% url 'projects:project_update' project.id %}" method="post">
        {% csrf_token %}
        <div class="forms">
            {{ form.id }}
            {{ form.non_field_errors }}
            {# Include the hidden fields #}
            {% for hidden in form.hidden_fields %}
                {{ hidden }}
            {% endfor %}
            <table id="id_table" class="table table-hover table-bordered table-condensed">
                <tbody>
                        <tr>
                            <td class="text-right">Title:</td>
                            <td>{{ form.title }}</td>
                        </tr>
                        <tr>
                            <td class="text-right">Champion:</td>
                            <td> <span id="id_champion_display">{{ project.champion }}</span> {{ form.champion_term }}  </td>
                        </tr>
                </tbody>
            </table>
        </div>
        <input type="submit" name="btn_update"  value="Update" class="btn btn-success btn-block" />
    </form>


    {% if messages %}
        <ul class="messages">
            {% comment %} https://getbootstrap.com/components/#alerts {% endcomment %}
            {% for message in messages %}
            <!--li{% if message.tags %} class="{{ message.tags }}"{% endif %} -->
                {% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
                    <div class="alert alert-danger" role="alert">{{ message }}</div>
                {% elif message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %}
                    <div class="alert alert-success" role="alert">{{ message }}</div>
                {% else %}
                    <div class="alert alert-info" role="alert">{{ message }}</div>
                {% endif %}
            <!-- /li -->
            {% endfor %}
        </ul>
    {% endif %}


{% endblock content %}


{# BEHAVIOR Javascript #}
{% block javascript %}
    {{ block.super }}

    {# http://code.jquery.com/ui/ #}
    <script src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

{% endblock javascript %}


{# DOM ready #}
{% block domready %}

    $( "#id_champion_term" ).autocomplete({
          {# http://api.jqueryui.com/autocomplete/#option-source #}
          source: "{% url 'projects:champion_get_json' %}",
          {# http://api.jqueryui.com/autocomplete/#option-autoFocus #}
          autoFocus:true,
          {# http://api.jqueryui.com/autocomplete/#option-minLength #}
          minLength:1,
          {# http://api.jqueryui.com/autocomplete/#event-select #}
          select:function(event,ui) {
              $("#id_champion").val(ui.item.id);
          }
    });

{% endblock %}

Add the jquery-ui javascript code

$( "#id_champion_display" ).autocomplete({
      source: "{% url champion_auto_complete %}",
      minLength:2,
      select:function(event,ui) {
        $("#id_champion").val(ui.item.id)
      }
});

Add the admin interface

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""Project Administration.

"""

from django.contrib import admin

from .models import Project

from .forms_django_autocomplete_light import ProjectFormDjangoAutocomplete

@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
    """Project administration

    Documentation
    =============

    - https://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-objects

    """
    form = ProjectFormDjangoAutocomplete
    list_display = ('title', 'champion')
    search_fields = ('title', 'champion')
    list_filter = ('title', 'champion')

Reading Project record from the commande line

python manage.py shell_plus


(ajax_django_35) C:\projects_id3\django_ajax_select\projet_ajax>python manage.py shell_plus
# Shell Plus Model Imports
from django.contrib.admin.models import LogEntry
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
from django.contrib.sessions.models import Session
from projects.models import Project
from singers.models import Author, Book, Group, Label, Person, Release, Song
# Shell Plus Django Imports
from django.db.models import Avg, Case, Count, F, Max, Min, Prefetch, Q, Sum, When
from django.db import transaction
from django.conf import settings
from django.utils import timezone
from django.urls import reverse
from django.core.cache import cache
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.

IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: p1=Project.objects.first()

In [2]: p1
Out[2]: <Project: project_0001 champion_0001>

In [3]: p1.id
Out[3]: 1

Add some users with the command line interface

The most direct way to create users is to use the included create_user() helper function:

In [4]: user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')

In [5]: user = User.objects.create_user('albert', 'albert@thebeatles.com', 'albertpassword')

In [6]: user = User.objects.create_user('zoya', 'zoya@thebeatles.com', 'zoyapassword')

In [7]: user = User.objects.create_user('nigel', 'nigel@thebeatles.com', 'nigelpassword')

In [8]: users=User.objects.all()

In [9]: users
Out[9]: <QuerySet [<User: admin>, <User: champion_0001>, <User: user_0002>, <User: user_0003>, <User: user_0004>, <User: aaaa>, <User: john>, <User: albert>, <User: zoya>, <User: nigel>]>

Try the URL : http://127.0.0.1:8000/projects/project/1/update

OK, this time this works fine !

Warning

La saisie est agréable, il faut améliorer le look.

../../../_images/ok_saisie_champion.png
[18/Oct/2016 15:17:26] "GET /projects/project/1/update/ HTTP/1.1" 200 3423
[18/Oct/2016 15:17:44] "GET /projects/champion_auto_complete/?term=zo HTTP/1.1" 200 45
[18/Oct/2016 15:17:51] "POST /projects/project/1/update/ HTTP/1.1" 302 0
[18/Oct/2016 15:17:51] "GET /projects/project/1/update/ HTTP/1.1" 200 3418
[18/Oct/2016 15:18:47] "GET /projects/champion_auto_complete/?term=ni HTTP/1.1" 200 48
[18/Oct/2016 15:19:00] "POST /projects/project/1/update/ HTTP/1.1" 302 0
[18/Oct/2016 15:19:00] "GET /projects/project/1/update/ HTTP/1.1" 200 3420