# fields.py
# -*- coding: utf-8 -*-
from django import forms
from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode
from django.core.urlresolvers import reverse
from django.forms.util import ErrorList, ValidationError
CLIENT_CODE = """
"""
class ModelAutoCompleteWidget(forms.widgets.TextInput):
""" widget autocomplete for text fields
"""
html_id = ''
def __init__(self,
lookup_url=None,
*args, **kw):
super(forms.widgets.TextInput, self).__init__(*args, **kw)
# url for Datasource
self.lookup_url = lookup_url
def render(self, name, value, attrs=None):
if value == None:
value = ''
html_id = attrs.get('id', name)
self.html_id = html_id
lookup_url = self.lookup_url
detail_url = reverse('ajax_platos_detail')
return mark_safe(CLIENT_CODE % (name, html_id, name, html_id, html_id,
lookup_url, html_id, html_id, detail_url))
def value_from_datadict(self, data, files, name):
"""
Given a dictionary of data and this widget's name, returns the value
of this widget. Returns None if it's not provided.
"""
return data.get(name, None)
class ModelAutoCompleteField(forms.fields.CharField):
"""
Autocomplete form field for Model Model
"""
model = None
url = None
def __init__(self, model, lookup_url, *args, **kwargs):
self.model, self.url = model, lookup_url
super(ModelAutoCompleteField, self).__init__(
widget = ModelAutoCompleteWidget(lookup_url=self.url),
max_length=255,
*args, **kwargs)
def clean(self, value):
try:
obj = self.model.objects.get(pk=value)
except self.model.DoesNotExist:
raise ValidationError(u'Invalid item selected')
return obj
# urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('mymodel.views',
# ajax
url(r'^ajax/list/$', 'ajax_mymodel_list',
name='ajax_mymodel_list'),
)
# views.py
from django.http import HttpResponse
from django.template import RequestContext
from mymodel.models import MyModel
def ajax_mymodel_list(request):
""" returns data displayed at autocomplete list -
this function is accessed by AJAX calls
"""
limit = 10
query = request.GET.get('q', None)
# it is up to you how query looks
if query:
qargs = [django.db.models.Q(name__istartswith=query)]
instances = MyModel.objects.filter(django.db.models.Q(*qargs))[:limit]
results = ""
for item in instances:
results += "%s|%s \n" %(item.pk,item.name)
return HttpResponse(results)
# forms.py
from django import forms
from django.core.urlresolvers import reverse
from mymodel.models import MyModel
from utils.fields import ModelAutoCompleteField
class TestForm(forms.Form):
theField = ModelAutoCompleteField(lookup_url = reverse('ajax_mymodel_list'),
model = MyModel, required=True)