KeyError: «менеджер» в django get_initial

Я работаю над FormView, и мне нужно установить initial из другого объекта, например, в моем случае мы используем модель Question, чтобы установить инициал для QuestionSuggestedEditsForm. Но мы получили ошибку при обновлении словаря initial.

1. models.py

@python_2_unicode_compatible
class Question(TimeStampedModel):
    author = models.ForeignKey(
        User, related_name='question_author')

    title = models.CharField(
        _('Title'), max_length=200)

    slug = models.SlugField(
        _('Slug'), max_length=200, unique=True)

    tags = models.ManyToManyField(
        Tag, related_name='tags')

    STATUS_CHOICES = (
        ('approved', _('Approved')),
        ('duplicated', _('Duplicated')),
        ('pending', _('Pending')),
        ('on_hold', _('On Hold')),
        ('closed', _('Closed')),
        ('deleted', _('Deleted'))
    )
    status = models.CharField(
        _('Status'), max_length=20,
        choices=STATUS_CHOICES, default='approved')

    description = models.TextField(_('Description'))

    rating = RatingField(can_change_vote=True)

    edited = models.BooleanField(
        _('Edited?'), default=False)

    editor = models.ForeignKey(
        User, blank=True, null=True,
        on_delete=models.SET_NULL, related_name='question_editor')

    objects = QuestionQuerySet.as_manager()

    def __str__(self):
        return self.title

    def _unique_slug(self):
        """
        return unique slug if origin slug is exist.
        eg: `foo-bar` => `foo-bar-1`
        """
        origin_slug = slugify(self.title)
        unique_slug = origin_slug
        numb = 1
        while Question.objects.filter(slug=unique_slug).exists():
            unique_slug = '%s-%d' % (origin_slug, numb)
            numb += 1
        return unique_slug

    def save(self, *args, **kwargs):
        if self.slug:  # edit
            if slugify(self.title) != self.slug:
                self.slug = self._unique_slug()
        else:  # create
            self.slug = self._unique_slug()
        super(Question, self).save(*args, **kwargs)

    def edits_object(self):
        question = self
        qs = QuestionSuggestedEdits.objects.filter(question=question)
        if qs.exists():
            return qs.first()
        return question

    class Meta:
        verbose_name_plural = _('questions')
        ordering = ['-created']


@python_2_unicode_compatible
class QuestionSuggestedEdits(TimeStampedModel):
    question = models.ForeignKey(
        Question, related_name='suggested_edits_question')

    editor = models.ForeignKey(
        User, related_name='suggested_edits_editor')

    title = models.CharField(
        _('Title'), max_length=200)

    slug = models.SlugField(
        _('Slug'), max_length=200, unique=True)

    tags = models.ManyToManyField(
        Tag, related_name='suggested_edits_tags')

    STATUS_CHOICES = (
        ('approved', _('Approved')),
        ('rejected', _('Rejected')),
        ('pending', _('Pending'))
    )
    status = models.CharField(
        _('Status'), max_length=20,
        choices=STATUS_CHOICES, default='pending')

    description = models.TextField(_('Description'))

    comment = models.TextField(_('Revision Comment'))

    class Meta:
        verbose_name_plural = _('question suggested edits')
        ordering = ['-created']

2. forms.py

class QuestionSuggestedEditsForm(forms.ModelForm):

    class Meta:
        model = QuestionSuggestedEdits
        fields = ['title', 'description', 'tags']

3. views.py

class QuestionSuggestedEditsCreate(LoginRequiredMixin, RevisionMixin, FormView):
    template_name = 'app_faq/question_suggested_edits_create.html'
    form_class = QuestionSuggestedEditsForm
    model = QuestionSuggestedEdits

    def get_object(self):
        return get_object_or_404(Question, pk=self.kwargs['pk'])

    def form_valid(self, form):
        initial = form.save(commit=False)
        initial.question = self.get_object()
        initial.editor = self.request.user
        initial.save()
        form.save_m2m()
        messages.success(self.request, _('Suggeste edits Question successfully created!'))
        return redirect(reverse('question_redirect', kwargs={'pk': initial.pk}))

    def get_initial(self):
        initial = super(QuestionSuggestedEditsCreate, self).get_initial()
        for field, _cls in self.form_class.base_fields.items():
            # print(field, _cls)
            # title <django.forms.fields.CharField object at 0xb54f4e2c>
            # description <django.forms.fields.CharField object at 0xb54f844c>
            # tags <django.forms.models.ModelMultipleChoiceField object at 0xb54f830c>

            value = getattr(self.get_object(), field) # got a value

            # print(field, '-', value)
            # title - Lorem ipsum dolor ismet title
            # description - Lorem ipsum dolor ismet description
            # tags - app_faq.Tag.None # maybe because this?

            # print(self.get_object().tags.all())
            # <QuerySet [<Tag: ajax>, <Tag: desktop>, <Tag: Django>]>

            #initial.update({field: 'no error'})

            initial.update({field: value}) # traceback started here..
        return initial

    def get_context_data(self, **kwargs):
        context = super(QuestionSuggestedEditsCreate, self).get_context_data(**kwargs)
        context['question'] = self.get_object()
        return context

И мы получили трассировку KeyError: 'manager';

Internal Server Error: /question/suggestion/edit/118/
Traceback (most recent call last):
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/core/handlers/base.py", line 217, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/core/handlers/base.py", line 215, in _get_response
    response = response.render()
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/response.py", line 107, in render
    self.content = self.rendered_content
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/response.py", line 84, in rendered_content
    content = template.render(context, self._request)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/backends/django.py", line 66, in render
    return self.template.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 207, in render
    return self._render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/loader_tags.py", line 177, in render
    return compiled_parent._render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/loader_tags.py", line 177, in render
    return compiled_parent._render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/loader_tags.py", line 72, in render
    result = block.nodelist.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 1046, in render
    return render_value_in_context(output, context)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/template/base.py", line 1024, in render_value_in_context
    value = force_text(value)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/utils/encoding.py", line 76, in force_text
    s = six.text_type(s)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/utils/html.py", line 385, in <lambda>
    klass.__str__ = lambda self: mark_safe(klass_str(self))
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/forms/boundfield.py", line 41, in __str__
    return self.as_widget()
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/forms/boundfield.py", line 101, in as_widget
    attrs = self.build_widget_attrs(attrs, widget)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/forms/boundfield.py", line 257, in build_widget_attrs
    if widget.use_required_attribute(self.initial) and self.field.required and self.form.use_required_attribute:
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/forms/boundfield.py", line 245, in initial
    data = self.form.get_initial_for_field(self.field, self.name)
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/forms/forms.py", line 506, in get_initial_for_field
    value = value()
  File "/home/agaust/ENV/env-django-faq/lib/python3.5/site-packages/django/db/models/fields/related_descriptors.py", line 842, in __call__
    manager = getattr(self.model, kwargs.pop('manager'))
KeyError: 'manager'
[22/Sep/2017 21:00:43] "GET /question/suggestion/edit/118/ HTTP/1.1" 500 217200

person binpy    schedule 22.09.2017    source источник
comment
Пожалуйста, покажите остальную часть трассировки. Какая строка в вашем коде вызывает это?   -  person Daniel Roseman    schedule 22.09.2017
comment
Как выглядят ваши модели?   -  person fiveclubs    schedule 22.09.2017
comment
@DanielRoseman Я обновил полную трассировку..   -  person binpy    schedule 22.09.2017


Ответы (1)


Речь идет об отношениях m2m, и с этим решено;

def get_initial(self):
    initial = super(QuestionSuggestedEditsCreate, self).get_initial()
    for field, _cls in self.form_class.base_fields.items():
        value = getattr(self.get_object(), field)
        if field == 'tags':
            value = self.get_object().tags.all()
        initial.update({field: value})
    return initial

Or;

def get_initial(self):
    initial = super(QuestionSuggestedEditsCreate, self).get_initial()
    for field, _cls in self.form_class.base_fields.items():
        value = getattr(self.get_object(), field)
        if _cls.__class__.__name__ == 'ModelMultipleChoiceField':
            m2m_instance = getattr(self.get_object(), field)
            value = m2m_instance.all()
        initial.update({field: value})
    return initial
person binpy    schedule 22.09.2017