Использование 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)
Надеюсь объяснил доступно
Python-сообщество
![]()
- Начало
- » 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'.
.
Использование related_name в Django
Я запутался в использовании related_name в моделях django, я знаю, что идея в том, чтобы дать мне доступ ко всем полям другой таблицы с помощью foreignkey, я просто не уверен, как это использовать.
class Component(MPTTModel): name = models.CharField(max_length=100) manufacturer = models.CharField(max_length=100) model = models.CharField(max_length=100) serial_number = models.CharField(max_length=255) price = models.IntegerField() note = models.TextField() image = models.ImageField(blank=True, null=True, upload_to='components_imgs') parent = TreeForeignKey("self", verbose_name=( "Parent Component"), blank=True, null=True, related_name='children', on_delete=models.CASCADE) def __str__(self): return f", " class Job(models.Model): job_type = ( ('I', 'Interval'), ('O', 'One time'), ) name = models.CharField(max_length=100) description = models.CharField(max_length=100) type = models.CharField(max_length=1, choices=job_type) interval = models.IntegerField() is_critical = models.BooleanField() due_date = models.DateField() component = models.ForeignKey( Component, related_name='jobs', on_delete=models.CASCADE) runninghours = models.ForeignKey( RunningHours, related_name="RHjobs", on_delete=models.CASCADE) def __str__(self): return self.name
def worklist(request): components = Component.objects.all() Component_jobs = components.jobs.all() context = return render(request,"worklist.html",context)
Я пытаюсь понять, почему эти строки дают мне ошибку ‘TreeQuerySet’ object has no attribute ‘jobs’
components = Component.objects.all() Component_jobs = components.jobs.all()
но эти строки работают просто отлично,
component = Component.objects.all() component_id = Component.objects.get(id=pk) job_id = component_id.jobs.all()
разве они не одинаковы, но в одном случае я получаю все задания для определенного ID, а в другом — все задания для всех компонентов?
Как описывает ошибка, этот код возвращает объект TreeQuerySet.
components = Component.objects.all()
Попытка вызвать поля типа price приведет к той же ошибке.
components = Component.objects.all() Component_jobs = components.price.all()
Причина, по которой этот код работает, заключается в том, что он вызывается на конкретном компоненте, а не на коллекции компонентов.
component = Component.objects.all() component_id = Component.objects.get(id=pk) job_id = component_id.jobs.all()
Чтобы получить все задания в наборе запросов, попробуйте использовать что-то вроде .values(‘jobs’) из queryset api reference
all_jobs = Component.objects.all().values('jobs')
Предположим, что вы хотите отобразить все компоненты в цикле, а затем отобразить все связанные задания для каждого компонента во вложенном цикле, ваш шаблон должен выглядеть примерно следующим упрощенным примером
Вы должны использовать prefetch_related для получения всех связанных заданий для всех компонентов в одном запросе. Нет необходимости запрашивать задания в представлении
components = Component.objects.all().prefetch_related('jobs')
Как использовать django related_name
I есть две модели с именами Meeting и MeetingMember следующим образом :
class Meeting(models.Model): title = models.CharField(max_length=255) description = models.TextField() class MeetingMember(models.Model): CHOICES = ( ("A", "Accepted"), ("R", "Rejected"), ("I", "Invited" ), ("H", "Host")) status = models.CharField(max_length=9, choices=CHOICES, default="I") meeting = models.ForeignKey(Meeting, on_delete=models.CASCADE, related_name="members") email = models.EmailField(blank=True)
Мне нужно написать запрос, который сначала получает все записи в модели MeetingMeember, принадлежащие текущему вошедшему пользователю, следующим образом :
meetingmembers = MeetingMember.objects.filter(email = request.user.email)
Затем мне нужно получить всю информацию из встреч, принадлежащих члену встречи (второй набор запросов должен быть объектом Meeting). Я изучал вопрос о related_name, но все еще не могу понять, как я могу написать это.
Атрибут related_name задает имя обратного отношения от модели Meeting обратно к модели MeetingMember.
Если у вас есть объект MeetingMember типа meeting_member и ваше related_name равно ‘members’, то meeting_member.members.all(), чтобы получить все экземпляры вашей модели Meeting, которые имеют отношение к объекту.
Вы можете фильтровать с помощью:
Meeting.objects.filter( members__email=request.user.email )
получить все Meeting , для которых email вошедший пользователь является членом.
Если вы работаете с моделью Member , вы можете использовать .select_related(…) [Django-doc] для получения объекта Meeting в том же запросе, тогда для some_member вы можете получить доступ к связанному Meeting (и информации с) some_member.meeting без дополнительного запроса:
meetingmembers = MeetingMember.objects.filter( email=request.user.email ).select_related('meeting') for member in meetingmenbers: print(member.meeting)
В соответствии с вашим проектом объект Meeting принадлежит нескольким объектам MeetingMember и вы можете получить к ним доступ, используя связанное имя members , например metting_obj.members.all() , а объект MeetingMember принадлежит одному объекту Meeting и вы можете оценить его, используя атрибут meeting , например metting_member_obj.metting
вы можете получить все Meeting объекты принадлежащие MeetingMember объектам следующим образом:
meeting_objs = [meeting_member.meeting for meeting_member in meetingmembers]