简体   繁体   中英

Django-autocomplete-light how to get data from html?

I can't get how to fetch data from HTML-element that contains data generated by django-autocomplete-light. Here is a code of the form:

class ThreadForm(forms.Form):
topic = forms.CharField(label="Topic", max_length=255)
body = forms.CharField(label="Body", widget=forms.Textarea(attrs={'rows': '12', 'cols':'100'}))
tags = autocomplete_light.fields.MultipleChoiceField(choices=(tuple((tag.name, tag.name) for tag in Tag.objects.all())),
                                      label='Tags',
                                      widget=autocomplete_light.widgets.MultipleChoiceWidget('TagAutocomplete',
                                                                                    attrs={'class':'form-control',
                                                                                           'placeholder':'Tag'}
                                                                                     )
                                                  )

def save(self, author, created):
  topic = self.cleaned_data['topic']
  body = self.cleaned_data['body']
  tags = self.cleaned_data['tags']
  th = Thread(author = author,
              topic = topic,
              body = body,
              created = created,
                )
  rtags = []
  for tag in tags:
      sr = Tag.objects.get(tag)
      rtags.append(sr.name)
  th.save()
  Tag.objects.update_tags(th, tags)

And autocomplete_light_registry.py:

from threads.models import Thread
import autocomplete_light
from tagging.models import Tag

class TagAutocomplete(autocomplete_light.AutocompleteModelBase):
    search_fields = ['^name']
autocomplete_light.register(Tag, TagAutocomplete, attrs={
    'data-autocomplete-minimum-characters': 1,
},)

As you see I've changed the django-autocomplete app. In the base.py I found a variable choice_html_format = '<span data-value="%s" name="choice">%s</span>' Attribute name was added by me to get data like that:

tags = request.POST.get('name')

But this doesn't work. I'm getting an error like "NoneType in not callable" Next thing I've tried is change choice_html from base.py :

def choice_html(self, choice):
    """
    Format a choice using :py:attr:`choice_html_format`.
    """
    return self.choice_html_format % (
        escape(self.choice_value(choice)),
        escape(self.choice_label(choice)))

It is original function, I've changed choice_value(choice) to choice_label(choice) . And got an error "invalid literal for int() with base 10: <tag_name_here>" . Looks like data-value attribute is only for int() type (but I can't get where I can change it, maybe in js-function, I don't know).

And the last, I'm trying to get the pk of each tag, and then get the name via manager. But I'm getting error Cannot resolve keyword '4' into field. Choices are: id, items, name Cannot resolve keyword '4' into field. Choices are: id, items, name .

I absolutely sure that there is an easy way to perform the task I need.

autocomplete-light has a template called widget.html that is rendered in the template:

...
{% block select %}
    {# a hidden select, that contains the actual selected values #}
    <select style="display:none" class="value-select" name="{{ name }}" id="{{ widget.html_id }}" multiple="multiple">
        {% for value in values %}
            <option value="{{ value|unlocalize }}" selected="selected">{{ value }}</option>
        {% endfor %}
    </select>
{% endblock %}
...

as you can see, this <select> element contains all selected choices for the autocomplete widget.

Its name (we are going to identify it by its name attribute later in the view) is simply the autocomplete's name ('tags').

So now you need to make sure your autocomplete field in the template is wrapped in <form> tags so the values get submitted (if you haven't already).

The next step is to retrieve the data in the view:

request.POST.getlist('tags')

That's it. You now have a list of primary keys of the selected values:

>>> print(str(request.POST.getlist('tags'))
['1', '3', '4', '7', ...]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM