首页 > 解决方案 > 如何更新 Django 表单中的 ManyToManyField 子属性?

问题描述

我有两种形式。我想更新也属于一本书的书名和课名。'ManyRelatedManager' object has no attribute '_meta'当我单击一本书的更新 url 时,我收到此错误。你想告诉我如何解决这个问题吗?这是错误的引用。

Traceback(most recent call last):
  File "/home/project/NLS/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
  response = get_response(request)
  File "/home/project/NLS/env/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
  response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/project/NLS/src/report/views.py", line 54, in book_update_form
  lession_form = LessonForm(instance=book.lesson)
  File "/home/project/NLS/env/lib/python3.8/site-packages/django/forms/models.py", line 294, in __init__
  object_data = model_to_dict(instance, opts.fields, opts.exclude)
  File "/home/project/NLS/env/lib/python3.8/site-packages/django/forms/models.py", line 85, in model_to_dict
  opts = instance._meta

Exception Type: AttributeError at / report/genrate/1/
Exception Value: 'ManyRelatedManager' object has no attribute '_meta'

模型.py

class Lesson(models.Model):
    name = models.CharField(max_length=10)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name


class Book(models.Model):
    title = models.CharField(max_length=10)
    created = models.DateTimeField(auto_now_add=True)
    lesson = models.ManyToManyField(Lesson)

    def __str__(self):
        return self.title

表格.py

class BookForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['title', 'lesson']


class LessonForm(forms.ModelForm):
    name = forms.CharField(max_length=10)

    class Meta:
        model = Lesson
        fields = ['name']

视图.py

def book_update_form(request, pk):
    book = get_object_or_404(Book, pk=pk)
    b_form = BookForm(request.POST, instance=book)
    l_form = [LessonForm(request.POST, prefix=str(
        lesson.pk), instance=lesson) for lesson in book.lesson.all()]

    if b_form.is_valid() and all([lf.is_valid() for lf in v_form]):
        book_update = b_form.save(commit=False)
        book_update.save()
        for lf in l_form:
            lesson_form = lf.save(commit=False)
            lesson_form.book = book_update
            lesson_form.save()
        return redirect('dashboard')
    else:
        book_update = BookForm(instance=book)
        lession_form = LessonForm(instance=book.lesson)
    context = {
        'book_update': book_update,
        'lesson_form': lesson_form
    }
    return render(request, 'update.html', context)

标签: djangodjango-modelsdjango-formsdjango-views

解决方案


  1. 你有错误[lf.is_valid() for lf in v_form]v_form没有定义,可能你想使用 l_form

  2. lesson_form.book = book_update. Lesson模型没有 book 属性,所以你不需要这一行

  3. 在您的else情况下,您创建lession_form = LessonForm(instance=book.lesson). book.lesson 是ManyToManyField,所以这里也有错误。我会这样重构你的代码:

def book_update_form(request, pk):
    book = get_object_or_404(Book, pk=pk)
    b_form = BookForm(request.POST or None, instance=book)
    l_form = [LessonForm(request.POST or None, prefix=str(
        lesson.pk), instance=lesson) for lesson in book.lesson.all()]

    if request.POST and b_form.is_valid() and all([lf.is_valid() for lf in l_form]):
        b_form.save()
        for lf in l_form:
            lesson_form = lf.save()
        return redirect('dashboard')
    context = {
        'book_update': b_form,
        'lesson_form': l_form# it's better to rename this variable to lesson_form_list
    }
    return render(request, 'update.html', context)

推荐阅读