доступ к данным ForeignKey django обратным способом

#django #orm

#django #orm

Вопрос:

У меня есть 2 модели

 class Book(models.Model):
  STATUS_CHOICES = (
      ('draft', 'Draft'),
      ('published', 'Publish')
    )
  name = models.CharField(max_length= 500)
  status = models.CharField(max_length = 10, 
                            choices = STATUS_CHOICES, 
                            default = 'draft')

class Author (models.Model):
  name = models.CharField(max_length)
  book = models.ForeignKey(Book, on_delete=models.CASCADE)
  

теперь я хочу реализовать запрос к таблице books и также получить его Author, я не хочу применять запрос к author, и myquery должен быть таким

 select * from book left join ON book.id = author.book_id where book.status = 'published'
  

Как я мог бы реализовать это в django

Комментарии:

1. Author Можно написать только одну книгу? Похоже, что моделирование должно быть отменено.

2. Несмотря на это, Django не допускает этого, поскольку это приведет к большой пропускной способности. Вы можете получить соответствующие источники во втором запросе. Однако, если есть ForeignKey from Book Author , вы можете сделать это в одном запросе.

Ответ №1:

Моделирование выглядит странно. Прямо сейчас это означает, что an Author публикует ровно одну книгу. Таким Author образом, An не может опубликовать ноль или более книг.

Вероятно, моделирование должно быть обратным: ForeignKey от Book до Author или ManyToManyField [Django-doc] в случае, если у a Book может быть несколько авторов:

 class Book(models.Model):
    STATUS_CHOICES = (
        ('draft', 'Draft'),
        ('published', 'Publish')
      )
    name = models.CharField(max_length= 500)
    status = models.CharField(
        max_length=10, 
        choices = STATUS_CHOICES, 
        default = 'draft',
        db_index=True
    )
    author = models.ForeignKey(
        'Author',
        related_name='books',
        on_delete=models.CASCADE
    )

class Author (models.Model):
  name = models.CharField(max_length=128)  

Можно выбирать объекты, ограниченные отношением «один к одному» ( OneToOneField ) или «многие к одному» ( ForeignKey ) с предложением .select_related(…) [Djanngo-doc]:

 Book.objects.filter(status='published').select_related('author')  

затем Author также выбираются данные, и Django обернет их в Author объекты, к которым вы можете получить доступ, точно так же, как вы получаете доступ ForeignKey к лениво mybook.author .

Для «один ко многим» (обратные ForeignKey s) и «многие ко многим» ( ManyToManyField s) это невозможно. Причина в том, что это может привести к огромной пропускной способности. Если у книги, например, пять авторов, это будет означать, что строки книг повторяются пять раз, что приводит к огромным откликам и низкой производительности. .prefetch_related(amp;hellip;) В этом случае можно использовать. Затем это приведет к массовому извлечению всех связанных объектов, предотвращая проблему N 1.

Если моделирование остается прежним, мы можем запросить Author выбор связанных книг с:

 Author.objects.filter(book__status='published').select_related('book')  

Комментарии:

1. если это нормально, то мой запрос должен быть таким же, я хочу реализовать запрос к автору и получить его книгу следующим образом: выберите * от автора, оставив книгу включенной…

2. если у вас есть какие-либо идеи, пожалуйста, поделитесь ими

3. @JaskaransinghRajal: это не тот же запрос, поскольку a LEFT OUTER JOIN является «асимметричным». Вы можете запросить у модели автора (см. Редактирование). Но все же моделирование выглядит странно. Странно, что автор может написать ровно одну книгу, а не несколько.

4. спасибо, я хочу, чтобы это работало нормально, что greate Author.objects.filter(book__status=’черновик’).select_related(‘книга’)

5. и о модели это просто пример