@mkone112
Начинающий питонист.

Как изменить порядок вывода элементов ManyToManyField?

Есть модель изображения, к которым пользователи могут ставить лайки.
class Image(models.Model):
    
    image = models.ImageField(upload_to='images/%Y/%m/%d/')

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        related_name='images_created',
        on_delete=models.CASCADE
    )
    
    # Пользователи лайкнувшие изображение.
    users_liked = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='images_liked',
        blank=True
    )

    title = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    url = models.URLField()
    slug = models.SlugField(max_length=200, blank=True)
    created = models.DateField(auto_now_add=True, db_index=True)

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('images:detail', args=(self.id, self.slug))

Я могу получить список всех лайкнувших изображение пользователей так:
from .models import Image
image = Image.objects.get(pk=1)

image.users_liked.all()

>> <QuerySet [<User: first_fake_user>, <User: second_fake_user>]>


Подскажите, как сделать чтобы каждый лайк имел отметку времени, иimage.users_liked.all() выводил пользователей в хронологическом порядке, согласно времени лайка?

Неудачная попытка:

Добавил промежуточную модель Like с дополнительным полем с отметкой времени, и указал ей `ordering`, но безрезультатно:
class Image(models.Model):

    image = models.ImageField(upload_to='images/%Y/%m/%d/')

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        related_name='images_created',
        on_delete=models.CASCADE
    )

    users_liked = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        through='Like',
        related_name='images_liked',
        blank=True
    )

    title = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    url = models.URLField()
    slug = models.SlugField(max_length=200, blank=True)
    created = models.DateField(auto_now_add=True, db_index=True)

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('images:detail', args=(self.id, self.slug))


class Like(models.Model):

    image = models.ForeignKey(Image, on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    liked_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ('liked_at',)


Кажется, параметр `ordering` ни на что не влияет(думаю это было ожидаемо):
image.users_liked.all()  >> <QuerySet [<User: first_fake_user>, <User: second_fake_user>]>

...
    class Like(models.Model):
        ...
        class Meta:
            ordering = ('-liked_at',)

image.users_liked.all()  >> <QuerySet [<User: first_fake_user>, <User: second_fake_user>]>

  • Вопрос задан
  • 101 просмотр
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы