LINUX.ORG.RU

Как работать с manytomany?

 , ,


0

1
class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField()
    authors = models.ManyToManyField(Author)
    number_of_comments = models.IntegerField()
    number_of_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __str__(self):
        return self.headline
>>> from apps.dictionaries.models import Entry,Blog,Author
>>> Entry.objects.all().values()[0]

out:

{'id': 1, 'headline': 'Entry_headline1', 'pub_date': datetime.date(2020, 7, 9), 'number_of_comments': 1, 'mod_date': datetime.date(2020, 7, 12), 'rating': 1, 'body_text': 'Entry_body_text1', 'blog_id': 1, 'number_of_pingbacks': 1}

Т.е нет field ‘authors’

Далее, если я явно указываю field authors, тогда получаю следующее:

>>> Entry.objects.all().values('authors')[0]

out:

{'authors': 2}

Как мне выбрать в нормальном виде? Т.е

 {'id': 1, 'headline': 'Entry_headline1', ..., 'authors': ['Author_name1'], ['Author_name2']
★★★★

Ответ на: комментарий от bryak

{‘id’: 1, ‘headline’: ‘Entry_headline1’, …, ‘authors’: [‘Author_name1’], [‘Author_name2’]

Никак. Тут нужно использовать сериалайзеры для получения списка авторов. И правильней было бы использовать related_name в описании поля MtM.

zad1ra ()
Последнее исправление: zad1ra (всего исправлений: 1)
Ответ на: комментарий от gruy

Общий запрос:

Entry.objects.all().values()[0]
{'number_of_pingbacks': 1, 'rating': 1, 'blog_id': 1, 'body_text': 'Entry_body_text1', 'headline': 'Entry_headline1', 'mod_date': datetime.date(2020, 7, 12), 'pub_date': datetime.date(2020, 7, 9), 'id': 1, 'number_of_comments': 1}

После запроса получаем следующее:

>>> Entry.objects.all().values('authors__name')[0]
{'authors__name': 'Author_name2'}

А хотелось бы так(по факту в записи идет привязка к двум Author_name):

{'authors__name': ['Author_name1', 'Author_name2']}

А вот так, всё ок

>>> Entry.objects.filter(id=1).values('authors__name')
<QuerySet [{'authors__name': 'Author_name1'}, {'authors__name': 'Author_name2'}]>
bryak ★★★★ ()
Последнее исправление: bryak (всего исправлений: 9)
Ответ на: комментарий от eternal_sorrow

Ты питонщик? Знакомься, это бряк. Когда он писал на котлине месяц назад, весь development был в RTFM-вопросах про котлин. ТС неисправим, просто игнорит советы почитать доки. Если подписан на тег, отписывайся, пока не устал.

cdshines ★★★★ ()
Ответ на: комментарий от eternal_sorrow

Знакомся, это cdshines. Он помогать не хочет, а только перегоняет воздух. Скорей всего, знаний у него чтобы помогать, - нет. Он ходит, наблюдает за мной, попутно пережовывая свою соплю

bryak ★★★★ ()
Последнее исправление: bryak (всего исправлений: 2)
Ответ на: комментарий от eternal_sorrow

Довольно смешное исправление. Во-первых, если и делать префетч, то вот так Entry.objects.all().prefetch_related('authors'), потому что name - строковое поле, а не связанная таблица, во-вторых зачем вообще нужен префетч? Правильно! Что бы при выборке кверисета джанга стразу притащила связанные объекты, и потом, когда юзер будет делать entry.name, джанго не ходил с дополнительными запросами в базу. Но тут-то автор сразу делает селекты нужных полей через values. Зачем тут префетч?

Aswed ★★★★★ ()