Search code examples
pythondjangodjango-formstaggingdjango-taggit

Django-taggit tag value retrieval and formatting failing


I am trying to implement a tagging process for profiles so you can add your hobbies for example. I have chosen django-taggit as it seemed quite simple and does what I need it to, plus don't really know how to do it myself from scratch. I have managed to make it work to some extent but I am having issues with 3 things:

  1. Not really sure what's the best way to control the form field for these tags as I generate the form automatically with widget adjustments in meta function of the form, but it might work fine after resolving the below two issues.
  2. When there is no data for the field hobbies (tags) the field gets populated with a single tag of value "[]" as per below image.

enter image description here

  1. When I add a tag of "music" and submit the form after I reload the page I get this "[]" as per image. I assumed this will be dealt with by the library, but I cannot see another similar scenario online.

enter image description here

When I try adding another tag of "games" and save and reload, the below happens. The initial value gets wrapped again.

enter image description here

My model is:

class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
hobbies = TaggableManager()

My form is:

class UserProfileForm(forms.ModelForm):

    class Meta:
        model = UserProfile
        fields = ['hobbies',]

    def __init__(self, *args, **kwargs):
      super(UserProfileForm, self).__init__(*args,**kwargs)
      self.fields['hobbies'].widget = forms.TextInput()
      self.fields['hobbies'].widget.attrs['data-role'] = "tagsinput"
      self.fields['hobbies'].widget.attrs['class'] = "form-control"
      self.fields['hobbies'].required = False

My view function is:

if request.method == 'POST':
        user_profile = UserProfile.objects.get(user=request.user)
        form = UserProfileForm(request.POST, instance=user_profile)
        print(form)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.user = request.user
            obj.save()
            print("Form valid")
            form.save_m2m()

Using:

<script src="/static/js/tagsinput.js"></script>
<link rel="stylesheet" href="{% static 'css/tagsinput.css' %}" />

Solution

  • So after quite a few (hundreds) of tests, I finally narrowed down where the issue was and tried to go around it with successful result. It seems the data got amended into tag objects through tagsinput library I was using. Only when the "data-role" was specified as "tagsinput" in the forms.py the data would already come to html side as those objects and be shown incorrectly. So instead I wanted to keep the data clean and only apply data-role='tagsinput' in the end for visual aspect, which I did using:

    var hobbiesTags = document.getElementById("id_hobbies");
      if(hobbiesTags){
      var att = document.createAttribute("data-role");
      att.value = "tagsinput";
      hobbiesTags.setAttributeNode(att);
      };
    

    And that resulted in the below. Maybe there are better ways to do this, I'm not sure, but it's a pretty clean solution. Share your alternatives.

    enter image description here