Django & Ajax: Как принять значение нескольких опций в select input и сохранить в базе данных

У меня есть форма, в которой я могу выбрать несколько тегов для одного проекта. Я использую поле ManyToMany для атрибута тега. Я использую AJAX для POST запроса с данными формы. Моя проблема в том, что форма не сохраняется с несколькими выбранными опциями. Есть решения?

--views.py

def create_project_view(request):
    form = ProjectForm()

    if request.is_ajax and request.method == 'POST':
        form = ProjectForm(request.POST, request.FILES)
        proj_title = request.POST.get('title', False)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.owner = request.user
            form.save()
            return JsonResponse({'title': proj_title}, status=200)

    context = {
        'form': form
    }
    return render(request, 'projects/project-form.html', context)

--проект-form.html с AJAX

   <main class="formPage my-xl">
    <div class="content-box">
        <div class="formWrapper">
            {% if project %}
            <a class="backButton" href="{% url 'project' project.id %}"><i class="im im-angle-left"></i></a>
            {% else %}
            <a class="backButton" href="{% url 'projects' %}"><i class="im im-angle-left"></i></a>
            {% endif %}
            <br>

            <form class="form" method="POST" id="form" action="" enctype="multipart/form-data">{% csrf_token %}
                {% for field in form %}
                <!-- Input:Text -->
                <div class="form__field">
                    <label for="formInput#text">{{field.label}}</label>
                    {{field}}
                </div>
                {% endfor %}
                <input class="btn btn--sub btn--lg  my-md" type="submit" value="Submit" />
            </form>
        </div>
    </div>
</main>
<script>
   $(document).ready(function(){
      $('#form').on('submit', function(e){

        e.preventDefault()
        var formData = new FormData();

        formData.append('title', $('#id_title').val())
        formData.append('description', $('#id_description').val())
        formData.append('featured_image', $('#id_featured_image')[0].files[0])
        formData.append('demo_link', $('#id_demo_link').val())
        formData.append('source_link', $('#id_source_link').val())
        formData.append('tags', $('#id_tags').val())
        formData.append('csrfmiddlewaretoken', $('input[name=csrfmiddlewaretoken]').val());
        console.log(formData)

        $.ajax({
          url: '{% url "create-project" %}',
          type: 'POST',
          data: formData,
          enctype: 'multipart/form-data',
          processData: false,
          contentType: false,
          success: function(response){
                alert('Project ' +response.title+  ' Added!')
                $('#id_title').val('')
                $('#id_description').val('')
                $('#id_featured_image').val('')
                $('#id_demo_link').val('')
                $('#id_source_link').val('')
                $('#id_tags').val('')
            },
          error: function(XMLHttpRequest, textStatus, errorThrown) {
                alert("Status: " + textStatus); alert("Error: " + errorThrown);
            }
          });
        });
      });
</script>

--models.py

    class Project(models.Model):
    owner = models.ForeignKey(User, default=None, on_delete=models.RESTRICT)
    title = models.CharField(max_length=200)
    description = models.TextField(null=True, blank=True)
    featured_image = models.ImageField(null=True, blank=True, default="default.jpg")
    demo_link = models.CharField(max_length=1000, null=True, blank=True)
    source_link = models.CharField(max_length=1000, null=True, blank=True)
    vote_total = models.IntegerField(default=0)
    vote_ratio = models.FloatField(default=0)
    tags = models.ManyToManyField('Tag', blank=True)
    created = models.DateTimeField(auto_now_add=True)
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)

    def full_name(self):
        return self.owner.get_full_name()

    def __str__(self):
        return self.title

    @property
    def imageURL(self):
        try:
            img = self.featured_image.url
        except:
            img = ''
        return img
    
class Review(models.Model):
    VOTE_TYPES = [
        ('up', 'up'),
        ('down', 'down')
    ]
    owner = models.ForeignKey(User, default=None, on_delete=models.CASCADE)
    project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True, blank=True)
    body = models.TextField(blank=True, default='')
    value = models.CharField(max_length=50, null=True, blank=True, choices=VOTE_TYPES)
    updated = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)

    def __str__(self):
        return self.project.title + " " + self.value + " " + self.owner.username
    
        
class Tag(models.Model):
    name = models.CharField(max_length=200)
    created = models.DateTimeField(auto_now_add=True)
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)

    def __str__(self):
        return self.name
Вернуться на верх