def update_note_tags(sender, instance, **kwargs):
    note_instance = instance

    # check if note has already been created
    if instance.pk:
         # Update tags if note content has changed
        old_note_instance = Note.objects.get(pk=note_instance.pk)

        if note_instance.content != old_note_instance.content:
            new_tags = set(Note.parsed_tags(note_instance.content))
            old_tags = set([t.keyword for t in old_note_instance.tags.all()])

            # Add tags new to the note
            tags_to_add = new_tags.difference(old_tags)
            tag_instances = []
            for t in tags_to_add:
                tag_instance, created = Tag.objects.get_or_create(keyword=t)
                tag_instances.append(tag_instance)
            note_instance.tags.add(*tag_instances)

            # Remove tags no longer present in note
            tags_to_remove = old_tags.difference(new_tags)
            tags_to_remove_set = Tag.objects.filter(keyword__in=tags_to_remove)
            note_instance.tags.remove(*tags_to_remove_set.all())

            remove_loose_tags(tag_queryset=tags_to_remove_set)
def update_created_note_tags(sender, instance, created=False, **kwargs):
    note_instance = instance
    if created:
        tag_instances = []
        # If Note is created, create associated Tags
        for t in Note.parsed_tags(note_instance.content):
            tag_instance, created = Tag.objects.get_or_create(keyword=t)
            tag_instances.append(tag_instance)

        note_instance.tags.add(*tag_instances)