Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
180 views
in Technique[技术] by (71.8m points)

Django ManyToManyField Persistence Fails

I have a simple Django 3.1.0 app I need to create in order to assign Tasks with Tags (or assign tags into tasks).

My Model

class Task(models.Model):
    user = models.CharField(max_length=33)
    time = models.DateTimeField(auto_now_add=True)
    task = models.CharField(max_length=500)
    tags = models.ForeignKey('Tag', on_delete=models.SET_NULL, null=True)

class Tag(models.Model):

    tag = models.CharField(max_length=30, default="No Tag")
    members = models.ManyToManyField('Task')

    class Meta:
        verbose_name = "tag"
        verbose_name_plural = "tags"

My Form

class TaskForm(ModelForm):
    class Meta:
        model = Task
        fields = ['user', 'task', 'tags']
        template_name = 'tasks.html'
    
    tags = ModelMultipleChoiceField(
        queryset=Tag.objects.values().all(), widget=CheckboxSelectMultiple()
    )

My View

def main(request):
    model = Task.objects.values().all()
    form = TaskForm()
    con = {'context': list(model), 'form': form}
    if request.method == 'POST':
      form = TaskForm(request.POST)
      if form.is_valid():
          obj = form.save(commit=False)
          form.save_m2m()
          return redirect('/')
    else:
        form = TaskForm()
    return render(request, "tasks.html", con)

The migrations are successfull, and with the above code, the view shows a checkbox list with the fetched tags, but the problem is that when I hit Submit on the form, the values are not saved/written on the database but the page reloads successfully.

However, if I turn the following:

          obj = form.save(commit=False)
          form.save_m2m()

into

          form.save(commit=True)
          #form.save_m2m()

the values are written only from the fields 'user', 'task' - without the 'tags'

It's also funny that what fetches back on the webpage as values of the tags is in the shape of:

[checkbox] {'id': 1, 'tag': 'aks'}

What am I doing wrong? Thanks.

UPDATE after a comment below:

As Abdul Aziz suggested, I had to remove the values() from the queryset. But after that , to make it work, I had to add also:

In the model:

    tag = models.CharField(max_length=100, default="No Tags")

and then refer to that one in the form and Vue template.

question from:https://stackoverflow.com/questions/65860276/django-manytomanyfield-persistence-fails

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You have a ForeignKey set to the Tag model on your Task model, when you actually want a ManyToMany relationship between them. Remove the foreign key and set a related_name to the ManyToManyField in the Tag model like so:

class Task(models.Model):
    user = models.CharField(max_length=33)
    time = models.DateTimeField(auto_now_add=True)
    task = models.CharField(max_length=500)

class Tag(models.Model):

    tag = models.CharField(max_length=30, default="No Tag")
    members = models.ManyToManyField('Task', related_name="tags")

    class Meta:
        verbose_name = "tag"
        verbose_name_plural = "tags"

Also in your form you have:

tags = ModelMultipleChoiceField(
    queryset=Tag.objects.values().all(), widget=CheckboxSelectMultiple()
)

Why are you using values here? Remove it:

tags = ModelMultipleChoiceField(
    queryset=Tag.objects.all(), widget=CheckboxSelectMultiple()
)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...