Get object or 404 django как работает
Перейти к содержимому

Get object or 404 django как работает

  • автор:

Python django get_object_or_404 внутри form_valid не работает

Надеюсь, вы сможете мне помочь, я изучаю django, в частности представления на основе классов, у меня есть следующий код.

Мне кажется, что get_object_or_404 внутри form_valid работает не так, как нужно.

class AgregarEntrada(CreateView): model = Entrada template_name = 'EntradaCrear.html' form_class = FormularioEntrada success_url = reverse_lazy('UltimasEntradas') def get_context_data(self, **kwargs): obj = get_object_or_404(Empresa, pk = self.kwargs["pk"], slug = self.kwargs["slug"], FechaCreacion = self.kwargs["FechaCreacion"]) contexto = super().get_context_data(**kwargs) return contexto def form_valid(self, form): obj = get_object_or_404(Empresa, pk = self.kwargs["pk"], slug = self.kwargs["slug"], FechaCreacion = self.kwargs["FechaCreacion"]) form.instance.empresa_id = self.kwargs["pk"] form.instance.UsuarioCreo = self.request.user.username self.object = form.save() form.instance.Entrada = form.instance.pk return super().form_valid(form) 

все работает идеально, это представление сохраняет данные правильно, даже если я перехожу к /pk/slug все работает нормально, аналогично, если я меняю slug или pk в url он сразу же отправляет мне ошибку 404, что так хорошо, проблема заключается в том, что когда кто-то меняет url после того, как форма была отображена, например, pk или slug, вместо того, чтобы отправить мне ошибку, он сохраняет данные, как будто pk или slug были правильными.

Я хочу объяснить лучше. Если я перехожу по url/pk/slug, все работает нормально, но когда кто-то переходит по url/pk/slug и меняет его на url/fake-pk/fake-slug, данные все равно сохраняются, как если бы url был правильным.

Что я делаю неправильно? Надеюсь, вы сможете понять мою проблему. Ребята я буду благодарен за любую помощь.

Вспомогательные функции Django¶

Пакет django.shortcuts собирает вспомогательные функции и классы, которые охватывают несколько уровней MVC. Другими словами, эти функции/классы для удобства вводят управляемую связь.

render() ¶

render ( request , template_name , context = None , content_type = None , status = None , using = None ) [исходный код] ¶

Объединяет заданный шаблон с заданным контекстным словарем и возвращает объект HttpResponse с этим визуализированным кодом.

Django не предоставляет функцию быстрого доступа, которая возвращает TemplateResponse , потому что конструктор TemplateResponse предлагает тот же уровень удобства, что и render() .

Обязательные аргументы¶

request Объект запроса, использованный для генерации этого ответа. template_name Полное имя используемого шаблона или последовательность имен шаблонов. Если указана последовательность, будет использован первый существующий шаблон. Смотрите документацию по загрузке шаблонов для получения дополнительной информации о том, как найти шаблоны.

Необязательные аргументы¶

context Словарь значений для добавления в контекст шаблона. По умолчанию это пустой словарь. Если значение в словаре является вызываемым, представление вызовет его непосредственно перед отрисовкой шаблона. content_type Тип MIME для использования в итоговом документе. По умолчанию — text/html . status Код состояния для ответа. По умолчанию 200 . using Параметр NAME шаблонизатора, который будет использоваться для загрузки шаблона.

Пример¶

В следующем примере отображается шаблон myapp/index.html с типом MIME application/xhtml+xml:

from django.shortcuts import render def my_view(request): # View code here. return render( request, "myapp/index.html",  "foo": "bar", >, content_type="application/xhtml+xml", ) 

Этот пример эквивалентен:

from django.http import HttpResponse from django.template import loader def my_view(request): # View code here. t = loader.get_template("myapp/index.html") c = "foo": "bar"> return HttpResponse(t.render(c, request), content_type="application/xhtml+xml") 

redirect() ¶

redirect ( to , * args , permanent = False , ** kwargs ) [исходный код] ¶

Возвращает HttpResponseRedirect на соответствующий URL-адрес для переданных аргументов.

Аргументами могут быть:

  • Модель: будет вызвана функция модели get_absolute_url() .
  • Имя представления, возможно с аргументами: reverse() , будет использоваться для обратного разрешения имени.
  • Абсолютный или относительный URL-адрес, который будет использоваться как есть для местоположения перенаправления.

По умолчанию выдает временное перенаправление; передайте permanent=True , чтобы выполнить постоянное перенаправление.

Примеры¶

Вы можете использовать функцию redirect() разными способами.

    Передавая некоторый объект; будет вызван метод этого объекта get_absolute_url() для определения URL перенаправления:

from django.shortcuts import redirect def my_view(request): . obj = MyModel.objects.get(. ) return redirect(obj) 
def my_view(request): . return redirect("some-view-name", foo="bar") 
def my_view(request): . return redirect("/some/url/") 

Это также работает с полными URL-адресами:

def my_view(request): . return redirect("https://example.com/") 

По умолчанию redirect() возвращает временное перенаправление. Все вышеперечисленные формы принимают permanent аргумент; если установлено значение True , будет возвращено постоянное перенаправление:

def my_view(request): . obj = MyModel.objects.get(. ) return redirect(obj, permanent=True) 

get_object_or_404() ¶

get_object_or_404 ( klass , * args , ** kwargs ) [исходный код] ¶ aget_object_or_404 ( klass , * args , ** kwargs

Асинхронная версия: aget_object_or_404()

Вызывает get() для данного менеджера модели, но вызывает исключение Http404 вместо DoesNotExist .

Аргументы¶

klass Класс Model , Manager или экземпляр QuerySet из которого получает объект. *args Q objects . **kwargs Параметры поиска, которые должны быть в формате, принятом get() и filter() .

Пример¶

Следующий пример получает объект с первичным ключом 1 из MyModel :

from django.shortcuts import get_object_or_404 def my_view(request): obj = get_object_or_404(MyModel, pk=1) 

Этот пример эквивалентен:

from django.http import Http404 def my_view(request): try: obj = MyModel.objects.get(pk=1) except MyModel.DoesNotExist: raise Http404("No MyModel matches the given query.") 

Наиболее распространенный вариант использования — передача Model , как показано выше. Однако вы также можете передать экземпляр QuerySet :

queryset = Book.objects.filter(title__startswith="M") get_object_or_404(queryset, pk=1) 

Приведенный выше пример немного надуман, поскольку он эквивалентен выполнению:

get_object_or_404(Book, title__startswith="M", pk=1) 

но это может быть полезно, если вам передали переменную queryset откуда-то еще.

Наконец, вы также можете использовать Manager . Это полезно, например, если у вас есть собственный менеджер :

get_object_or_404(Book.dahl_objects, title="Matilda") 

Вы также можете использовать связанные менеджеры :

author = Author.objects.get(name="Roald Dahl") get_object_or_404(author.book_set, title="Matilda") 

Примечание: как и в случае с get() , исключение MultipleObjectsReturned будет вызвано, если будет найдено более одного объекта.

Changed in Django 5.0:

Добавлена функция aget_object_or_404() .

get_list_or_404() ¶

get_list_or_404 ( klass , * args , ** kwargs ) [исходный код] ¶ aget_list_or_404 ( klass , * args , ** kwargs

Асинхронная версия: aget_list_or_404()

Возвращает результат filter() для заданного менеджера модели, приведенного к списку, вызывая Http404 , если результирующий список пустой.

Аргументы¶

klass Model , Manager или QuerySet , из которого можно получить список. *args Q objects . **kwargs Параметры поиска, которые должны быть в формате, принятом get() и filter() .

Пример¶

Следующий пример получает все опубликованные объекты из MyModel :

from django.shortcuts import get_list_or_404 def my_view(request): my_objects = get_list_or_404(MyModel, published=True) 

Этот пример эквивалентен:

from django.http import Http404 def my_view(request): my_objects = list(MyModel.objects.filter(published=True)) if not my_objects: raise Http404("No MyModel matches the given query.") 

Changed in Django 5.0:

Добавлена функция aget_list_or_404() .

Использование метода get_object_or_404()

На данный момент, если пользователь вручную запрашивает несуществующую тему или запись, он получает ошибку сервера 500. Django пытается отобразить страницу, но не располагает достаточной информацией для этого, что приводит к ошибке 500. Такая ситуация более точно обрабатывается как ошибка 404, и это поведение можно реализовать при помощи вспомогательной функции Django get_object_or_404(). Эта функция пытается получить запрошенный объект из базы данных, а если этот объект не существует — инициирует исключение 404. Мы импортируем эту функцию в views.py и используем ее вместо get():

from django.shortcuts import render, get_object_or_404

from django.http import HttpResponseRedirect, Http404

def topic(request, topic_id):

«»»Выводит одну тему и все ее записи.»»»

# Проверка того, что тема принадлежит текущему пользователю.

Use get_object_or_404 in Django to write lesser code

For the sake of an example, let us consider a model called Record that is defined as follows:

If you had to write an API to fetch a particular Record object using the id field. It would look something like this:

These 4 lines of code can be converted into a single line of code using get_object_or_404:

TL;DR

To retrieve objects from a database, use get_object_or_404 as opposed to getting the object using the ORM way and throwing an exception if it does not exist. This method pretty much does the same thing under the hood.

�� �� Enjoyed reading?

I write about navigating my life around being a technical co-founder of a startup, leveraging Django to build SaaS products and leading a wholesome life.
Subscribe to my weekly newsletter to get notified on new content published every Sunday. I promise to deliver value and not BS ��

Click here if you don’t see the subscribe form.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *