def test_with_comma_delimited_multiple_words_disabled_space_split(self, mocked_settings): mocked_settings.TAGGIT_ENABLE_SPACE_SPLIT_IF_NOT_QUOTES = False tools.assert_equals(parse_tags(',one'), [u'one']) tools.assert_equals(parse_tags(',one two'), [u'one two']) tools.assert_equals(parse_tags(',one two three'), [u'one two three']) tools.assert_equals(parse_tags('a one, a-two and a-three'), [u'a one', u'a-two and a-three'])
def test_custom_comma_splitter(self): self.assertEqual(parse_tags(" Cued Speech "), ["Cued Speech"]) self.assertEqual(parse_tags(" ,Cued Speech, "), ["Cued Speech"]) self.assertEqual(parse_tags("Cued Speech"), ["Cued Speech"]) self.assertEqual( parse_tags("Cued Speech, dictionary"), ["Cued Speech", "dictionary"] )
def test_tags_with_double_quotes_can_contain_commas_disabled_space_split( self, mocked_settings): mocked_settings.TAGGIT_ENABLE_SPACE_SPLIT_IF_NOT_QUOTES = False tools.assert_equals(parse_tags('a-one "a-two, and a-three"'), [u'a-one', u'a-two, and a-three']) tools.assert_equals(parse_tags('"two", one, one, two, "one"'), [u'two', u'one'])
def test_tags_with_double_quotes_can_contain_commas(self): """ Double quotes can contain commas """ self.assertEqual(parse_tags('a-one "a-two, and a-three"'), ['a-one', 'a-two, and a-three']) self.assertEqual(parse_tags('"two", one, one, two, "one"'), ['one', 'two'])
def test_with_simple_space_delimited_tags(self): """ Test with simple space-delimited tags. """ self.assertEqual(parse_tags("one"), ["one"]) self.assertEqual(parse_tags("one two"), ["one", "two"]) self.assertEqual(parse_tags("one two three"), ["one", "three", "two"]) self.assertEqual(parse_tags("one one two two"), ["one", "two"])
def test_with_comma_delimited_multiple_words_disabled_space_split( self, mocked_settings): mocked_settings.TAGGIT_ENABLE_SPACE_SPLIT_IF_NOT_QUOTES = False tools.assert_equals(parse_tags(',one'), [u'one']) tools.assert_equals(parse_tags(',one two'), [u'one two']) tools.assert_equals(parse_tags(',one two three'), [u'one two three']) tools.assert_equals(parse_tags('a one, a-two and a-three'), [u'a one', u'a-two and a-three'])
def test_tags_with_double_quotes_can_contain_commas(self): """ Double quotes can contain commas """ tools.assert_equals(parse_tags('a-one "a-two, and a-three"'), [u'a-one', u'a-two, and a-three']) tools.assert_equals(parse_tags('"two", one, one, two, "one"'), [u'one', u'two'])
def test_with_simple_space_delimited_tags(self): """ Test with simple space-delimited tags. """ self.assertEqual(parse_tags('one'), [u'one']) self.assertEqual(parse_tags('one two'), [u'one', u'two']) self.assertEqual(parse_tags('one two three'), [u'one', u'three', u'two']) self.assertEqual(parse_tags('one one two two'), [u'one', u'two'])
def test_tags_with_double_quotes_can_contain_commas(self): """ Double quotes can contain commas """ self.assertEqual(parse_tags('a-one "a-two, and a-three"'), [u'a-one', u'a-two, and a-three']) self.assertEqual(parse_tags('"two", one, one, two, "one"'), [u'one', u'two'])
def test_with_simple_space_delimited_tags(self): """ Test with simple space-delimited tags. """ self.assertEqual(parse_tags('one'), ['one']) self.assertEqual(parse_tags('one two'), ['one', 'two']) self.assertEqual(parse_tags('one two three'), ['one', 'three', 'two']) self.assertEqual(parse_tags('one one two two'), ['one', 'two'])
def import_row(self, row): # generate slugs row['name'] = row['name'].strip() row['email'] = row['email'].lower() if row['url'] and not row['url'].startswith(('http://', 'https://')): row['url'] = 'http://' + row['url'] row['slug'] = slugify(row['name']) row['classification'] = self.get_classification( row.pop('classification__slug', None)) categories = parse_tags(row.pop('categories', '')) categories = list(self.get_categories(categories)) tags = parse_tags(row.pop('tags', '')) # Backwards compatible handling of topic__slug topic_slug = row.pop('topic__slug', None) if topic_slug: tags.append(self.get_topic(topic_slug)) # resolve foreign keys row['jurisdiction'] = self.get_jurisdiction( row.pop('jurisdiction__slug')) parent = row.pop('parent__name', None) if parent: row['parent'] = PublicBody.objects.get(slug=slugify(parent)) # get optional values for n in ('description', 'other_names', 'request_note', 'website_dump'): row[n] = row.get(n, '') try: if 'id' in row and row['id']: pb = PublicBody.objects.get(id=row['id']) else: pb = PublicBody.objects.get(slug=row['slug']) # If it exists, update it row.pop('id', None) # Do not update id though row['_updated_by'] = self.user PublicBody.objects.filter(id=pb.id).update(**row) pb.laws.clear() pb.laws.add(*row['jurisdiction'].laws) pb.tags.set(*tags) pb.categories.set(*categories) return pb except PublicBody.DoesNotExist: pass row.pop('id', None) # Remove id if present public_body = PublicBody(**row) public_body._created_by = self.user public_body._updated_by = self.user public_body.confirmed = True public_body.site = self.site public_body.save() public_body.laws.add(*row['jurisdiction'].laws) public_body.tags.set(*list(tags)) return public_body
def test_with_comma_delimited_multiple_words(self): """ Test with comma-delimited multiple words. An unquoted comma in the input will trigger this. """ self.assertEqual(parse_tags(",one"), ["one"]) self.assertEqual(parse_tags(",one two"), ["one two"]) self.assertEqual(parse_tags(",one two three"), ["one two three"]) self.assertEqual(parse_tags("a-one, a-two and a-three"), ["a-one", "a-two and a-three"])
def test_with_simple_space_delimited_tags(self): """ Test with simple space-delimited tags. """ tools.assert_equals(parse_tags('one'), [u'one']) tools.assert_equals(parse_tags('one two'), [u'one', u'two']) tools.assert_equals(parse_tags('one two three'), [u'one', u'three', u'two']) tools.assert_equals(parse_tags('one one two two'), [u'one', u'two'])
def clean_expertise(self): """Enforce expertise as a subset of interests""" # bug 709938 - don't assume interests passed validation interests = set(parse_tags(self.cleaned_data.get("interests", ""))) expertise = set(parse_tags(self.cleaned_data["expertise"])) if len(expertise) > 0 and not expertise.issubset(interests): raise forms.ValidationError(_("Areas of expertise must be a " "subset of interests")) return self.cleaned_data["expertise"]
def test_with_comma_delimited_multiple_words(self): """ Test with comma-delimited multiple words. An unquoted comma in the input will trigger this. """ self.assertEqual(parse_tags(',one'), [u'one']) self.assertEqual(parse_tags(',one two'), [u'one two']) self.assertEqual(parse_tags(',one two three'), [u'one two three']) self.assertEqual(parse_tags('a-one, a-two and a-three'), [u'a-one', u'a-two and a-three'])
def test_with_comma_delimited_multiple_words(self): """ Test with comma-delimited multiple words. An unquoted comma in the input will trigger this. """ self.assertEqual(parse_tags(',one'), ['one']) self.assertEqual(parse_tags(',one two'), ['one two']) self.assertEqual(parse_tags(',one two three'), ['one two three']) self.assertEqual(parse_tags('a-one, a-two and a-three'), ['a-one', 'a-two and a-three'])
def test_with_double_quoted_multiple_words(self): """ Test with double-quoted multiple words. A completed quote will trigger this. Unclosed quotes are ignored. """ self.assertEqual(parse_tags('"one'), ["one"]) self.assertEqual(parse_tags('"one two'), ["one", "two"]) self.assertEqual(parse_tags('"one two three'), ["one", "three", "two"]) self.assertEqual(parse_tags('"one two"'), ["one two"]) self.assertEqual(parse_tags('a-one "a-two and a-three"'), ["a-one", "a-two and a-three"])
def clean_expertise(self): """Enforce expertise as a subset of interests""" # bug 709938 - don't assume interests passed validation interests = set(parse_tags(self.cleaned_data.get('interests', ''))) expertise = set(parse_tags(self.cleaned_data['expertise'])) if len(expertise) > 0 and not expertise.issubset(interests): raise forms.ValidationError(_("Areas of expertise must be a " "subset of interests")) return self.cleaned_data['expertise']
def test_with_double_quoted_multiple_words(self): """ Test with double-quoted multiple words. A completed quote will trigger this. Unclosed quotes are ignored. """ tools.assert_equals(parse_tags('"one'), [u'one']) tools.assert_equals(parse_tags('"one two'), [u'one', u'two']) tools.assert_equals(parse_tags('"one two three'), [u'one', u'three', u'two']) tools.assert_equals(parse_tags('"one two"'), [u'one two']) tools.assert_equals(parse_tags('a-one "a-two and a-three"'), [u'a-one', u'a-two and a-three'])
def test_with_double_quoted_multiple_words(self): """ Test with double-quoted multiple words. A completed quote will trigger this. Unclosed quotes are ignored. """ self.assertEqual(parse_tags('"one'), ['one']) self.assertEqual(parse_tags('"one two'), ['one', 'two']) self.assertEqual(parse_tags('"one two three'), ['one', 'three', 'two']) self.assertEqual(parse_tags('"one two"'), ['one two']) self.assertEqual(parse_tags('a-one "a-two and a-three"'), ['a-one', 'a-two and a-three'])
def clean_expertise(self): """Enforce expertise as a subset of interests""" cleaned_data = self.cleaned_data interests = set(parse_tags(cleaned_data['interests'])) expertise = set(parse_tags(cleaned_data['expertise'])) if len(expertise) > 0 and not expertise.issubset(interests): raise forms.ValidationError(_("Areas of expertise must be a " "subset of interests")) return cleaned_data['expertise']
def clean_expertise(self): """Enforce expertise as a subset of interests""" cleaned_data = self.cleaned_data interests = set(parse_tags(cleaned_data['interests'])) expertise = set(parse_tags(cleaned_data['expertise'])) if len(expertise) > 0 and not expertise.issubset(interests): raise forms.ValidationError( _("Areas of expertise must be a " "subset of interests")) return cleaned_data['expertise']
def tag_all(self, request, queryset): """ Tag all selected requests with given tags """ opts = self.model._meta # Check that the user has change permission for the actual model if not self.has_change_permission(request): raise PermissionDenied # User has already chosen the other req if request.POST.get('tags'): tags = parse_tags(request.POST.get('tags')) for obj in queryset: obj.tags.add(*tags) obj.save() self.message_user(request, _("Successfully added tags to requests")) # Return None to display the change list page again. return None context = { 'opts': opts, 'queryset': queryset, 'media': self.media, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'applabel': opts.app_label } # Display the confirmation page return TemplateResponse(request, 'foirequest/admin_tag_all.html', context, current_app=self.admin_site.name)
def read_csv(source, csv_stream): """ Reads metadata from a CSV for a specified source name. """ if not isinstance(source, Source): source = Source.objects.get(name=source) from csvkit import CSVKitReader rows = list(CSVKitReader(csv_stream, delimiter='\t')) fields = dict(enumerate(rows[0])) errors = [] for row in rows[1:]: try: data = {fields[idx]: value for idx, value in enumerate(row)} tags = data.pop('tags', None) dataset = Dataset(**data) dataset.source = source dataset.save() if tags: dataset.tags.add(*parse_tags(tags)) except Exception, e: logger.exception('Cannot import a dataset from CSV') errors.append(repr(e))
def search(self): # First, store the SearchQuerySet received from other processing. if self.cleaned_data['q']: sqs = super(objectSearchForm, self).search() else: sqs= SearchQuerySet().exclude(draft=True) if not self.is_valid(): return self.no_query_found() # Check to see if a start_date was chosen. if self.cleaned_data['tags']: sqs = sqs.filter(tags=parse_tags(self.cleaned_data['tags'])) # if 'start_date' in self.cleaned_data: # sqs = sqs.filter(created__gte=self.cleaned_data['start_date']) # Check to see if an end_date was chosen. # if 'end_date' in self.cleaned_data: # sqs = sqs.filter(created=self.cleaned_data['end_date']) if not self.cleaned_data['sort'] or self.cleaned_data['sort'] == "votes": sqs = sqs.order_by('-ratingSortBest') elif self.cleaned_data['sort'] == "new": sqs = sqs.order_by('-created') return sqs
def render(self, name, value, attrs=None, renderer=None): """ Render HTML code """ options = '' if value is not None and not isinstance(value, six.string_types): value = [o.tag for o in value.select_related('tag')] value = edit_string_for_tags(value) options = [ '<option value="{value}" selected>{value}</option>'.format( value=escape(six.text_type(o))) for o in parse_tags(value)] options = '\n'.join(options) html = super(TagAutocompleteWidget, self).render( name, value, attrs, renderer=renderer ) html = """<div style="display: none">%(input)s</div><select id="%(objectid)s_select2" name="%(objectid)s_select2" multiple>%(options)s</select> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', function () { window.Froide.components.tagautocomplete.setupTagging('%(objectid)s', '%(sourceurl)s', { noResults: '%(noResults)s', searching: '%(searching)s' }) }); </script>""" % dict( input=html, objectid=attrs['id'], sourceurl=self.autocomplete_url, options=options, noResults=_('No results'), searching=_('Searching…') ) return mark_safe(html)
def render(self, name, value, attrs=None): if value is not None: if isinstance(value, basestring): value = parse_tags(value) else: value = edit_string_for_tags([o.tag for o in value.select_related("tag")]) return super(TagWidget, self).render(name, value, attrs)
def reprocess_tags(self): self.stdout.write( 'Reprocessing tags (lowercasing, slugifying, etc.)...') project_total = Project.objects.count() # Use an iterator so the queryset isn't stored in memory # This may take a long time but should be memory efficient for i, project in enumerate(Project.objects.iterator()): old_tags_objs = list(project.tags.all()) if old_tags_objs: old_tags = sorted([t.name for t in old_tags_objs]) old_tag_string = edit_string_for_tags(old_tags_objs) new_tags = parse_tags(old_tag_string) # Update the tags on the project if they are different # Note: "parse_tags" handles sorting if new_tags != old_tags: if not self.dry_run: self.stdout.write( '[{}/{}] Setting tags on "{}"'.format( i + 1, project_total, project.slug, )) project.tags.set(*new_tags) else: self.stdout.write( '[{}/{}] Not setting tags on "{}" (dry run)'. format( i + 1, project_total, project.slug, ))
def import_bookmark(request, template_name='bookmark/import_bookmark.html'): file_form = FileForm(request.POST or None, request.FILES or None) if request.method == 'POST' and file_form.is_valid(): file = request.FILES['file'] tags_input = file_form.cleaned_data['tags'] public = file_form.cleaned_data['public'] try: bookmarks = parse_firefox_bookmark(file) for bk in bookmarks: try: bookmark = Bookmark.objects.create(url=bk['url'], title=bk['title'], owner=request.user, public=public) if tags_input: tags = tags_input else: tags = parse_tags(bk['tags']) for tag in tags: bookmark.tags.add(tag) # Update the screen shot update_bk_screen_shot_async(bookmark) except Exception: pass return HttpResponseRedirect(reverse("my_bookmark")) except Exception, e: file_form._errors[NON_FIELD_ERRORS] = ErrorList([e.message])
def clean_tags(self): """ Validate the tags ensuring we have no case-sensitive duplicates. """ tags = self.cleaned_data['tags'] cleaned_tags = [] if tags: for tag in parse_tags(tags): # Note: The exact match query doesn't work correctly with # MySQL with regards to case-sensitivity. If we move to # Postgresql in the future this code may need to change. doc_tag = (DocumentTag.objects.filter(name__exact=tag) .values_list('name', flat=True)) # Write a log we can grep to help find pre-existing duplicate # document tags for cleanup. if len(doc_tag) > 1: log.warn('Found duplicate document tags: %s' % doc_tag) if doc_tag: if doc_tag[0] != tag and doc_tag[0].lower() == tag.lower(): # The tag differs only by case. Do not add a new one, # add the existing one. cleaned_tags.append(doc_tag[0]) continue cleaned_tags.append(tag) return ' '.join([u'"%s"' % t for t in cleaned_tags])
def clean(self, value): value = super(TagField, self).clean(value) value = ','.join(SIO(value)) try: return parse_tags(value) except ValueError: raise forms.ValidationError(_("Please provide a comma-separated list of tags."))
def clean(self, value): value = super().clean(value) try: return parse_tags(value) except ValueError: raise forms.ValidationError( _("Please provide a comma-separated list of tags."))
def profile_edit(request, username): """View and edit user profile""" profile = get_object_or_404(UserProfile, user__username=username) if not profile.allows_editing_by(request.user): return HttpResponseForbidden() # Map of form field names to tag namespaces field_to_tag_ns = ( ('interests', 'profile:interest:'), ('expertise', 'profile:expertise:') ) if request.method != "POST": initial = dict(email=profile.user.email) # Load up initial websites with either user data or required base URL for name, meta in UserProfile.website_choices: val = profile.websites.get(name, '') or meta['prefix'] initial['websites_%s' % name] = val # Form fields to receive tags filtered by namespace. for field, ns in field_to_tag_ns: initial[field] = ', '.join(t.name.replace(ns, '') for t in profile.tags.all_ns(ns)) # Finally, set up the form. form = UserProfileEditForm(instance=profile, initial=initial) else: form = UserProfileEditForm(request.POST, request.FILES, instance=profile) if form.is_valid(): profile_new = form.save(commit=False) # Gather up all websites defined by the model, save them. sites = dict() for name, meta in UserProfile.website_choices: field_name = 'websites_%s' % name field_value = form.cleaned_data.get(field_name, '') if field_value: sites[name] = field_value profile_new.websites = sites # Save the profile record now, since the rest of this deals with # related resources... profile_new.save() # Update tags from form fields for field, tag_ns in field_to_tag_ns: tags = [t.lower() for t in parse_tags( form.cleaned_data.get(field, ''))] profile_new.tags.set_ns(tag_ns, *tags) return HttpResponseRedirect(reverse( 'devmo.views.profile_view', args=(profile.user.username,))) return jingo.render(request, 'devmo/profile_edit.html', dict( profile=profile, form=form, INTEREST_SUGGESTIONS=INTEREST_SUGGESTIONS ))
def save(self, user): artwork, created = Artwork.objects.get_or_create( name=self.cleaned_data['artwork_name'], kind=self.cleaned_data['artwork_kind'], creator=self.cleaned_data['artwork_creator'], year=self.cleaned_data['artwork_year'], ) if artwork.kind == 'show': # Allow unlimited reviews: review, created = Review.objects.get_or_create( pk=self.cleaned_data['review_id'], user=user, artwork=artwork, season=self.cleaned_data['artwork_season'], episode=self.cleaned_data['artwork_episode'], ) else: review, created = Review.objects.get_or_create( user=user, artwork=artwork, ) review.spider_quantity = self.cleaned_data['spider_quantity'] review.summary = self.cleaned_data['summary'] review.spider_quality.set( *parse_tags(self.cleaned_data['spider_quality']) ) review.save() return review
def profile_edit(request, username): """View and edit user profile""" profile = get_object_or_404(UserProfile, user__username=username) if not profile.allows_editing_by(request.user): return HttpResponseForbidden() # Map of form field names to tag namespaces field_to_tag_ns = ( ('interests', 'profile:interest:'), ('expertise', 'profile:expertise:') ) if request.method != 'POST': initial = dict(email=profile.user.email) # Load up initial websites with either user data or required base URL for name, meta in UserProfile.website_choices: initial['websites_%s' % name] = profile.websites.get(name, '') # Form fields to receive tags filtered by namespace. for field, ns in field_to_tag_ns: initial[field] = ', '.join(t.name.replace(ns, '') for t in profile.tags.all_ns(ns)) # Finally, set up the form. form = UserProfileEditForm(instance=profile, initial=initial) else: form = UserProfileEditForm(request.POST, request.FILES, instance=profile) if form.is_valid(): profile_new = form.save(commit=False) # Gather up all websites defined by the model, save them. sites = dict() for name, meta in UserProfile.website_choices: field_name = 'websites_%s' % name field_value = form.cleaned_data.get(field_name, '') if field_value and field_value != meta['prefix']: sites[name] = field_value profile_new.websites = sites # Save the profile record now, since the rest of this deals with # related resources... profile_new.save() # Update tags from form fields for field, tag_ns in field_to_tag_ns: tags = [t.lower() for t in parse_tags( form.cleaned_data.get(field, ''))] profile_new.tags.set_ns(tag_ns, *tags) return HttpResponseRedirect(reverse( 'devmo.views.profile_view', args=(profile.user.username,))) return render(request, 'devmo/profile_edit.html', dict( profile=profile, form=form, INTEREST_SUGGESTIONS=INTEREST_SUGGESTIONS ))
def clean(self, value): try: # only accept letters, digits, and spaces if re.search(r'[^a-zA-Z0-9 ]', value) is not None: raise ValueError return parse_tags(value.lower()) except ValueError: raise ValidationError('Please provide a space-separated list of tags.')
def clean(self, value): value = super().clean(value) try: return parse_tags(value) except ValueError: raise forms.ValidationError( _("Please provide a comma-separated list of tags.") )
def render(self, name, value, attrs=None): if value is not None: if isinstance(value, basestring): value = parse_tags(value) else: value = edit_string_for_tags( [o.tag for o in value.select_related("tag")]) return super(TagWidget, self).render(name, value, attrs)
def process_zipfile(self): from photologue.utils.upload import upload_file if path.isfile(self.zip_file.path): try: zip = zipfile.ZipFile(self.zip_file.path) bad_file = zip.testzip() except: bad_file = self.zip_file.path if bad_file: raise Exception('"%s" in the .zip archive is corrupt.' % bad_file) parsed_tags = parse_tags(self.tags) if self.gallery: gallery = self.gallery self.title = gallery.title else: gallery = Gallery.objects.create( title=self.title, title_slug=slugify(self.title), description=self.description, is_public=self.is_public, ) gallery.save() gallery.tags.add(*parsed_tags) count = 0 def read_file(fn): try: return zip.read(fn) except: return None for filename in sorted(zip.namelist()): data = zip.read(filename) file_mtime = zip.getinfo(filename).date_time file_mtime = make_aware(datetime(*file_mtime), get_current_timezone()) if self.use_title: name = os.path.basename(filename) namebase, ext = os.path.splitext(name) name = "".join([self.title, ext]) else: name = filename count = upload_file( name, filename, data, file_mtime, read_file, parsed_tags, gallery, self.caption, self.is_public, count, ) if not self.use_title: count = 0 zip.close()
def clean_tags(self): value = self.cleaned_data['tags'] print 'value' print value try: # self.cleaned_data['tags'] = parse_tags(value) # print 'cleaned' # print self.cleaned_data['tags'] return parse_tags(value) except ValueError: raise forms.ValidationError(_("Please provide a comma-separated list of tags."))
def test_with_naughty_input(self): """ Test with naughty input. """ # Bad users! Naughty users! self.assertEqual(parse_tags(None), []) self.assertEqual(parse_tags(""), []) self.assertEqual(parse_tags('"'), []) self.assertEqual(parse_tags('""'), []) self.assertEqual(parse_tags('"' * 7), []) self.assertEqual(parse_tags(",,,,,,"), []) self.assertEqual(parse_tags('",",",",",",","'), [","]) self.assertEqual(parse_tags('a-one "a-two" and "a-three'), ["a-one", "a-three", "a-two", "and"])
def _extract_tags(self, request): # We let this throw a KeyError so that calling functions will know if # there were NO tags in the request or if there were, but that the # call had an empty tags list in it. raw_tags = request.POST['tags'] tags = [] if raw_tags: try: tags = [t for t in parse_tags(raw_tags) if len(t)] except Exception, e: pass
def from_native(self, data): if isinstance(data, list): return self._strict_tags(data) if isinstance(data, six.string_types): try: return self._strict_tags(parse_tags(data)) except ValueError: pass raise ValidationError(self.error_messages['invalid'])
def get_context(self, name, value, attrs): ctx = super().get_context(name, value, attrs) ctx['autocomplete_url'] = self.autocomplete_url if value is not None: if isinstance(value, str): ctx['tags'] = parse_tags(value) else: ctx['tags'] = [v.name for v in value] else: ctx['tags'] = [] return ctx
def get_context(self, name, value, attrs): ctx = super().get_context(name, value, attrs) ctx['autocomplete_url'] = self.autocomplete_url if value is not None: if isinstance(value, str): ctx['tags'] = parse_tags(value) else: ctx['tags'] = [v.tag.name for v in value] else: ctx['tags'] = [] return ctx
def make_current(self): """Make this revision the current one for the document""" self.document.title = self.title self.document.slug = self.slug self.document.html = self.content_cleaned self.document.current_revision = self # Since Revision stores tags as a string, we need to parse them first # before setting on the Document. self.document.tags.set(*parse_tags(self.tags)) self.document.save()
def clean(self, value): value = super(CustomTagField, self).clean(value) print '----CustomTagField form clean exicuted' if value: try: print '----CustomTagField parse_tags exicuted' return parse_tags(value) except ValueError: print '****CustomTagField ValueError' raise forms.ValidationError("Provide one or more comma-separated tags.") else: return value
def render(self, name, value, attrs=None, renderer=None): """ Render HTML code """ options = '' if value is not None and not isinstance(value, six.string_types): value = [o.tag for o in value.select_related('tag')] value = edit_string_for_tags(value) options = [ '<option value="{value}" selected>{value}</option>'.format( value=escape(six.text_type(o))) for o in parse_tags(value)] options = '\n'.join(options) html = super(TagAutocompleteWidget, self).render( name, value, attrs, renderer=renderer ) html = """<div style="display: none">%(input)s</div><select id="%(objectid)s_select2" name="%(objectid)s_select2" multiple>%(options)s</select> <script type="text/javascript"> document.addEventListener('DOMContentLoaded', function() { $('#%(objectid)s_select2').on('change.select2', function(e) { var tagString = $(this).select2('data').map(function(el){ return '"' + el.id + '"'; }).join(', '); $('#%(objectid)s').val(tagString); }).select2({ width: '75%%', tags: true, tokenSeparators: [',', ' '], ajax: { url: '%(sourceurl)s', data: function (params) { if (params.term.length === 0) { return null; } return { query: params.term }; }, processResults: function(data) { return { results: data.map(function(el) { return { id: el, text: el } }) } } } }) }); </script>""" % dict( input=html, objectid=attrs['id'], sourceurl=self.autocomplete_url, options=options ) return mark_safe(html)
def test_with_naughty_input(self): """ Test with naughty input. """ # Bad users! Naughty users! self.assertEqual(parse_tags(None), []) self.assertEqual(parse_tags(''), []) self.assertEqual(parse_tags('"'), []) self.assertEqual(parse_tags('""'), []) self.assertEqual(parse_tags('"' * 7), []) self.assertEqual(parse_tags(',,,,,,'), []) self.assertEqual(parse_tags('",",",",",",","'), [',']) self.assertEqual(parse_tags('a-one "a-two" and "a-three'), ['a-one', 'a-three', 'a-two', 'and'])
def test_with_naughty_input(self): """ Test with naughty input. """ # Bad users! Naughty users! tools.assert_equals(parse_tags(None), []) tools.assert_equals(parse_tags(''), []) tools.assert_equals(parse_tags('"'), []) tools.assert_equals(parse_tags('""'), []) tools.assert_equals(parse_tags('"' * 7), []) tools.assert_equals(parse_tags(',,,,,,'), []) tools.assert_equals(parse_tags('",",",",",",","'), [u',']) tools.assert_equals(parse_tags('a-one "a-two" and "a-three'), [u'a-one', u'a-three', u'a-two', u'and'])
def test_with_naughty_input(self): """ Test with naughty input. """ # Bad users! Naughty users! self.assertEqual(parse_tags(None), []) self.assertEqual(parse_tags(''), []) self.assertEqual(parse_tags('"'), []) self.assertEqual(parse_tags('""'), []) self.assertEqual(parse_tags('"' * 7), []) self.assertEqual(parse_tags(',,,,,,'), []) self.assertEqual(parse_tags('",",",",",",","'), [u',']) self.assertEqual(parse_tags('a-one "a-two" and "a-three'), [u'a-one', u'a-three', u'a-two', u'and'])
def clean(self, value): value = super(MeetingTopicField, self).clean(value) try: tag_names = parse_tags(value) except ValueError: raise forms.ValidationError(_("Please provide a comma-separated list of tags.")) tags = [] for tag_name in tag_names: tag, created = models.MeetingTopic.objects.get_or_create(name=tag_name) tags.append(tag.id) return tags