Related name django как использовать
Перейти к содержимому

Related name django как использовать

  • автор:

Зачем нужен related_name в Django?

В мире Django, ORM (Object-Relational Mapping) играет важную роль в взаимодействии с базой данных. Однако, иногда возникают ситуации, когда нужно обращаться к связанным моделям. Вот здесь на помощь приходит related_name .

Допустим, у нас есть две модели: Book и Author . Одна книга может иметь много авторов, и один автор может написать много книг. В таком случае, мы скажем, что у модели Book и Author есть отношение «многие ко многим» или ManyToMany .

from django.db import models class Book(models.Model): title = models.CharField(max_length=200) authors = models.ManyToManyField('Author') class Author(models.Model): name = models.CharField(max_length=100)

Когда мы хотим получить все книги определенного автора, мы можем просто использовать author.book_set.all() . Здесь book_set — это автоматически создаваемое Django имя для обратной связи от модели Author к Book .

Но что, если мы хотим использовать более осмысленное имя вместо book_set ? Тут на помощь приходит related_name .

from django.db import models class Book(models.Model): title = models.CharField(max_length=200) authors = models.ManyToManyField('Author', related_name='books') class Author(models.Model): name = models.CharField(max_length=100)

Теперь, вместо book_set , можно использовать books для обращения ко всем книгам автора. Таким образом, related_name используется для создания более осмысленного и удобного имени для обратной связи между моделями.

В заключение хотелось бы подчеркнуть, что использование related_name повышает читаемость и понимание кода, что особенно важно в больших и сложных проектах.

Использование related_name во view-функции

Оно не должно совпадать с другими related_name для указанной модели.

В примере из вашего кода, что я привел выше, для модели User доступно обращение к связанным объектам модели Post по имени posts . Т.о. Больше нигде вы не сможете указать related_name=’posts’ если это связь с моделью User .

Если обращение из другой модели не требуется, можно указать related_name=’+’

Зачем

related_name позволяет обращаться к из связанных объектов к тем, от которых эта связь была создана.

class Post(models.Model): text = models.TextField() pub_date = models.DateTimeField(auto_now_add=True) author = models.ForeignKey( User, on_delete=models.CASCADE, related_name='posts' ) group = models.ForeignKey(Group, on_delete=models.CASCADE, max_length=200, blank=True, null=True, related_name='group') 

related_name дожно быть posts , чтобы из модели Group , а вернее из объектов этой модели, можно было достать все связанные объекты Post по логичному наименованию.

В общем должно быть так

class Post(models.Model): text = models.TextField() pub_date = models.DateTimeField(auto_now_add=True) author = models.ForeignKey( User, on_delete=models.CASCADE, related_name='posts' ) group = models.ForeignKey(Group, on_delete=models.CASCADE, max_length=200, blank=True, null=True, related_name='posts') 

И тогда для группы можно будет получить все посты следущим способом

posts = group.posts.all() 
Ревью

Что касается ревью, то на основе описанного выше должно получиться так

 def group_posts(request, slug): group = get_object_or_404(Group, slug=slug) posts = group.posts.order_by('-pub_date')[:10] context = < 'group': group, 'posts': posts, >return render(request, 'posts/group_list.html', context) 

Надеюсь объяснил доступно

Как проверить related_name

Шаг первый — находим в коде модель данных с related_name . Для примера возьмём код онлайн-библиотеки:

class Book(models.Model): author = models.ForeignKey( User, verbose_name='автор', related_name='authors' ) 

У нас есть книги и их авторы. Поле related_name позволяет развернуть это отношение и для каждого автора получить список его книг.

Теперь открываем Django shell и пишем запрос с related_name . Выберем любого пользователя из БД и узнаем какие книги он написал:

$ python manage.py shell >>> from users.models import User >>> user = User.objects.first() >>> user.authors.all() 

Внимательно перечитываем свой код и видим: хотели книги — books , а получили неких авторов authors . Что за дичь здесь происходит ?!

Исправляем неудачное название related_name на логичное и понятное:

user.author_books.all() 

Осторожнее с пользователями!

В примере выше вместо author_books можно написать books . Так получится короче и смысл не потеряется. Так может показаться на первый взгляд, но это не так. Очень часто в модели данных содержится сразу несколько ссылок на учётки пользователей. У книги помимо авторов могут быть рецензенты, читатели, фоловеры и много кого ещё. Всё это ссылки на пользователей и у каждой связи есть свой собственный related_name . Если назвать related_name без уточнений как books , то в связях легко будет запутаться, не ясно о чём речь в запросе об авторстве или о лайках.

Если в модели данных одна связь с пользователями, то это ещё не значит, что в будущем их не станет больше. Функционал сайта постоянно расширяется и лишь одно остаётся в мире неизменным — “требования меняются всегда!”

Попробуйте бесплатные уроки по Python

Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

Переходите на страницу учебных модулей «Девмана» и выбирайте тему.

Python-сообщество

[RSS Feed]

  • Начало
  • » Django
  • » related_name зачем оно?

#1 Сен. 7, 2008 02:00:08

romankrv От: Зарегистрирован: 2008-05-23 Сообщения: 513 Репутация: 0 Профиль Отправить e-mail

related_name зачем оно?

You can override the FOO_set name by setting the related_name parameter in the ForeignKey() definition. For example, if the Entry model was altered to blog = ForeignKey(Blog, related_name=’entries’), the above example code would look like this:

Понятно что этим мы перекрываем название менеджера FOO_set который возвращает все экземпляры молели по схеме бэкворд (foirgin key) на свой.

Вопрос для каких практических целей это используется так как это вроде вносит лишние имена при работе. Что в этом есть удобного ?

#2 Сен. 7, 2008 08:43:40

Lolka От: Зарегистрирован: 2007-09-29 Сообщения: 128 Репутация: 0 Профиль Отправить e-mail

related_name зачем оно?

Пример – модель трижды завешена на User по разным причинам :

model Labyrinth(models.Model): 
designer = models.ForeignKey(User, null=False, related_name='designer') # дизайнер
curator = models.ForeignKey(User, null=True, related_name='curator') # куратор
manager = models.ForeignKey(User, null=True, related_name='manager') # менеджер

Если не указать related_name, то получится такое:

Error: One or more models did not validate:
labyrinths.labyrinth: Accessor for field 'designer' clashes with related field 'User.labyrinth_set'. Add a related_name argument to the definition for 'designer'.
labyrinths.labyrinth: Accessor for field 'curator' clashes with related field 'User.labyrinth_set'. Add a related_name argument to the definition for 'curator'.
.

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

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