Как исправить «объект __proxy__» не имеет атрибута «get» »при попытке ошибочно обновить форму - PullRequest
2 голосов
/ 18 мая 2019

Ребята, у меня простая модель книги:

class Book(models.Model):
    isbn = models.CharField(_('ISBN'),
        validators=[RegexValidator('^[0-9 -]+$', message="ISBN must contains only numbers or hyphens!")] ,
        max_length=13, unique=True)
    title = models.CharField(_('Book\'s title'), max_length=128)
    publisher = models.CharField(_('Publisher'), max_length=64)
    author = models.CharField(_('Author'), max_length=64)
    pages = models.IntegerField(_('Pages'), default=0)
    created_at = models.DateTimeField(auto_now_add=True, editable=False)
    updated_at = models.DateTimeField(auto_now=True, editable=False)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('books:detail', kwargs={'isbn': self.isbn})

Я кодирую систему crud и у меня возникли проблемы с UpdateView.Это представление работает правильно, когда я пытаюсь выполнить правильное обновление, но когда я вставляю неправильные значения (например, буквы в isbn или буквы на страницах), у меня появляется эта ошибка:

Reverse for 'update' with arguments '('31234-11a',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['books/update/(?P<isbn>[\\d\\-]+)/$']

EDIT : Это мое мнение:

class BookUpdateView(UpdateView):
    """Update the requested book."""
    model = Book
    form_class = BookForm

    def get_object(self):
        pk = self.kwargs.get(self.pk_url_kwarg, None)
        queryset = self.get_queryset()
        queryset = queryset.filter(isbn=self.kwargs['isbn'])
        if not queryset.exists():
            messages.error(self.request, 'This book doesnt exist!')
            return get_object_or_404(Book, **self.kwargs)
        return queryset.get()

    def get_success_url(self):
        messages.success(self.request, 'The book updated successfully!')
        return reverse_lazy('books:detail', kwargs = {'isbn': self.object.isbn})

    def form_invalid(self, form):
        messages.error(self.request, 'The update has failed')
        return self.render_to_response(self.get_context_data(form=form))

и мой URL-адрес обновления:


urlpatterns = [
    url(r'^update/(?P<isbn>[\d\-]+)/$', view=views.BookUpdateView.as_view(), name='update'),
]

Мне нужно использовать Django 1.10 в этом проекте idk почему.Если кто-то может порекомендовать мне материал для чтения или ответить на вопрос, будет приятно.Спасибо

1 Ответ

1 голос
/ 18 мая 2019

Ваши form_valid и form_invalid методы могут не возвращать объект lazy_reverse(..), поскольку это не HTTP-ответ.

Однако вы можете использовать redirect(..) [Django-doc] , который будет создавать ответ HTTP, например:

from django.shortcuts import <b>redirect</b>

class BookUpdateView(UpdateView):
    """Update the requested book."""
    model = Book
    form_class = BookForm

    # ...

    def get_success_url(self):
        messages.success(self.request, 'The book updated successfully!')
        return reverse_lazy('books:detail', kwargs = {'isbn': self.object.isbn})

    def form_invalid(self, form):
        messages.error(self.request, 'The update has failed')
        return <b>redirect('books:index')</b>

Вероятно, вы можете немного улучшить свой метод get_object с помощью:

from django.http import <b>Http404</b>
from django.shortcuts import redirect

class BookUpdateView(UpdateView):
    """Update the requested book."""
    model = Book
    form_class = BookForm

    def get_object(self):
        queryset = self.get_queryset()
        try:
            return queryset.get(isbn=self.kwargs['isbn'])
        except:
            messages.error(self.request, 'This book doesnt exist!')
            raise Http404('Book does not exist')

Однако не очень распространено для redirect(..) в случае form_invalid(..).Обычно шаблон перерисовывается с такой формой, что форма отображается с сообщениями об ошибках.Поэтому переопределение метода form_invalid не очень распространено: по умолчанию Django переопределяет шаблон с неверной формой.

EDIT : вы можете перенаправить страницу на другую страницу, еслиisbn не сопоставляется с действительным следующим образом:

from django.core.exceptions import <b>ObjectDoesNotExist</b>
from django.http import <b>Http404</b>
from django.shortcuts import redirect

class BookUpdateView(UpdateView):
    """Update the requested book."""
    model = Book
    form_class = BookForm

    # ...

    def get(self, *args, **kwargs):
        <b>try:</b>
            self.object = self.get_object()
        <b>except (ObjectDoesNotExist, Http404):</b>
            return <b>redirect('books:index')</b>
        return self.render_to_response(self.get_context_data())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...