Исправление render () получило неожиданный ключевой аргумент renderer в Django 2.1 - PullRequest
0 голосов
/ 24 января 2019

Я воскрешаю старый код, который используется для работы в Django 1.9. Я пытаюсь преобразовать этот код в Django 2.1, но этот пакет, который является частью моего проекта, имеет некоторые проблемы с совместимостью. Я пытаюсь исправить ошибку типа render ().

Я искал возможный устаревший код, как и другие подобные сообщения, но я не могу ничего найти, например виджеты. Я попытался добавить рендер в тело в виджете forms.py, но это тоже не сработало.

Views.py

@login_required
def compose(request, recipient=None, form_class=ComposeForm,
        template_name='django_messages/compose.html', 
success_url=None, recipient_filter=None):
    """
    Displays and handles the ``form_class`` form to compose new 
messages.
    Required Arguments: None
    Optional Arguments:
    ``recipient``: username of a `django.contrib.auth` User, who should
                   receive the message, optionally multiple usernames
                   could be separated by a '+'
    ``form_class``: the form-class to use
    ``template_name``: the template to use
    ``success_url``: where to redirect after successfull submission
"""
if request.method == "POST":
    sender = request.user
    form = form_class(request.POST, recipient_filter=recipient_filter)
    if form.is_valid():
        form.save(sender=request.user)
        messages.info(request, _(u"Message successfully sent."))
        if success_url is None:
            success_url = reverse('messages_inbox')
        if 'next' in request.GET:
            success_url = request.GET['next']
        return HttpResponseRedirect(success_url)
else:
    form = form_class()
    if recipient is not None:
        recipients = [u for u in User.objects.filter(
            **{'%s__in' % get_username_field(): [r.strip() for r in recipient.split('+')]})]
        form.fields['recipient'].initial = recipients
return render(request, template_name, {
    'form': form,
})

Forms.py

class ComposeForm(forms.Form):
    """
    A simple default form for private messages.
    """
    recipient = CommaSeparatedUserField(label=_(u"Recipient"))
    subject = forms.CharField(label=_(u"Subject"), max_length=140)
    body = forms.CharField(label=_(u"Body"),
                           widget=forms.Textarea(attrs={'rows': '12', 'cols': '55'}))

    def __init__(self, *args, **kwargs):
        recipient_filter = kwargs.pop('recipient_filter', None)
        super(ComposeForm, self).__init__(*args, **kwargs)
        if recipient_filter is not None:
            self.fields['recipient']._recipient_filter = recipient_filter

    def save(self, sender, parent_msg=None):
        recipients = self.cleaned_data['recipient']
        subject = self.cleaned_data['subject']
        body = self.cleaned_data['body']
        message_list = []
        for r in recipients:
            msg = Message(
                sender=sender,
                recipient=r,
                subject=subject,
                body=body,
            )
            if parent_msg is not None:
                msg.parent_msg = parent_msg
                parent_msg.replied_at = timezone.now()
                parent_msg.save()
            msg.save()
            message_list.append(msg)
            if notification:
                if parent_msg is not None:
                    notification.send([sender], "messages_replied", {'message': msg, })
                    notification.send([r], "messages_reply_received", {'message': msg, })
                else:
                    notification.send([sender], "messages_sent", {'message': msg, })
                    notification.send([r], "messages_received", {'message': msg, })
        return message_list

А вот и обратная связь:

  File "/Users/justinboucher/PycharmProjects/awaylm/django_messages/views.py", line 96, in compose
    'form': form,

  File "/anaconda3/envs/awaylm/lib/python3.6/site-packages/django/forms/boundfield.py", line 33, in __str__
    return self.as_widget()
  File "/anaconda3/envs/awaylm/lib/python3.6/site-packages/django/forms/boundfield.py", line 93, in as_widget
    renderer=self.form.renderer,
TypeError: render() got an unexpected keyword argument 'renderer'
[24/Jan/2019 03:57:26] "GET /messages/compose/ HTTP/1.1" 500 188278

1 Ответ

0 голосов
/ 07 февраля 2019

У меня была такая же проблема, и она оказалась одной из моих зависимостей.

Сначала я добавил отладочную информацию в Django, чтобы я мог видеть причину проблемы, поэтому я отредактировал приведенный ниже файл Django.(в моем virtualenv, чтобы ничего не нарушать в глобальном пакете Django):

vi site-packages / django / forms / boundfield.py

Ваш журнал журнала сервера будет идентифицировать конкретный файлдля вас.

Я добавил вызов "help" в строке 50:

        if self.auto_id and 'id' not in widget.attrs:
            attrs.setdefault('id', self.html_initial_id if only_initial else self.auto_id)
        help(widget.render)
        return widget.render(
            name=self.html_initial_name if only_initial else self.html_name,
            value=self.value(),
            attrs=attrs,
            renderer=self.form.renderer,
        )

Затем я перезапустил свой сервер Django, чтобы он выполнил функцию справки, и в журнале сервера я увиделследующее:

Help on method render in module codemirror.widgets:

render(name, value, attrs=None) method of codemirror.widgets.CodeMirror instance
    Render the widget as an HTML string.

Это указывает на проблему совместимости между Django и django-codemirror, которая является зависимостью, которую я использовал для визуализации некоторого содержимого в форме.

Я решил дополнительно изменитьФайл Django, чтобы разрешить виджеты без аргумента рендерера.Это не идеальное решение, но мне не нужно возиться с исходными файлами django-codemirror.

        if self.auto_id and 'id' not in widget.attrs:
            attrs.setdefault('id', self.html_initial_id if only_initial else self.auto_id)
        # help(widget.render)
        try:
            return widget.render(
            name=self.html_initial_name if only_initial else self.html_name,
            value=self.value(),
            attrs=attrs,
            renderer=self.form.renderer,
        )
        except:
            return widget.render(
            name=self.html_initial_name if only_initial else self.html_name,
            value=self.value(),
            attrs=attrs
        )

Надеюсь, этот процесс поможет определить конкретный объект, который несовместим в вашей среде.

Edit: с тех пор я решил изменить Django обратно на код по умолчанию и внес изменения, необходимые в моей копии django-codemirror.Я оставлю свой ответ выше на тот случай, если кто-то еще захочет изменить Django для работы с другими зависимостями.

Также зафиксирована следующая проблема: https://github.com/onrik/django-codemirror/issues/3

...