Задать вопрос

Как избавиться от дублирования информации в django?

имеется примерно такая модель:

class Series(models.Model):
    title = models.CharField(max_length=400)
    description = models.TextField(blank=True)

class Book(models.Model):
    title = models.CharField(max_length=400)
    description = models.TextField(blank=True)
    series = models.ManyToManyField(Series, through='BookSeries', blank=True)
    summary = models.ForeignKey(BookSummary)


class BookSummary(models.Model):
    original_title = models.CharField(max_length=400)
    description = models.TextField(blank=True)


class BookSeries(models.Model):
    book = models.ForeignKey(Book)
    series = models.ForeignKey(Series)
    booksummary = models.ForeignKey(BookSummary)
    position = models.IntegerField()

    def save(self, *args, **kwargs):
        self.booksummary = self.book.summary
        super(BookSeries, self).save(*args, **kwargs)

т.е. как все знают есть много видов одной книги, на разных языках, с разными переводчиками и прочее, к примеру на goodreads: https://www.goodreads.com/book/show/3 и https://www.goodreads.com/book/show/43507 книга одна, отличия в описании, присутствии переводчика и т.д.

задача: с помощью модели BookSummary нужно решить подобную задачу: свести информацию о всех одинаковых книгах на одну страничку.

проблема: при такой вьюхе

class BooksSummary(DetailView):
    model = BookSummary

    def get_context_data(self, **kwargs):
        context = super(BooksSummary, self).get_context_data(**kwargs)
        context['books'] = self.object.book_set.all()
        context['series'] = self.object.bookseries_set.all()  # проблема тут
        return context

все хорошо выводится, то, что надо, т.е. на страничке агрегаторе всех книг выводятся все серии к которым принадлежат все версии этой книги. НО проблема в том, что выводятся и одинаковые серии. т.е. если на странице информация о 3 версиях книги и они все принадлежат к какой-то серии, то на странице трижды будет выводится эта серия, а нужно что бы только один раз, ведь там все совпадает. distinct() тут не помогает как я понимаю из-за поля book в модели BookSeries, удалять его нельзя. Как решить проблему с этим дублем информации?

пробовал во вьюхе еще вот так:

context['series'] = Series.objects.filter(book__summary=self.object).distinct()

так тоже выводится то, что надо и без дублей, но тогда не получается получить доступ к полю position из модели BookSeries со страницы BookSummary
  • Вопрос задан
  • 703 просмотра
Подписаться 3 Оценить 5 комментариев
Решения вопроса 1
@NerVik Автор вопроса
Проблему решил, хоть и не очень нравящимся мне способом. не чувствую от него удовлетворения ;)

до этого момента на дев версия была на SQLite, ради удобства. Пришлось перейти на PostgreSQL ради улучшенного .distinct().

теперь вьюха выглядит примерно так:

class BooksSummary(DetailView):
    model = BookSummary

    def get_context_data(self, **kwargs):
        context = super(BooksSummary, self).get_context_data(**kwargs)
        context['books'] = self.object.book_set.all()
        context['series'] = self.object.bookseries_set.all()\
            .select_related('series',
                            'book',
                            'booksummary')\
            .order_by('series')\
            .distinct('series')
        return context
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
syschel
@syschel
freelance/python/django/backend
Если все книги подвязаны к сериям, а все серии уникальны (нет дублей). То нужно выводить именно серии. А уже в темплайте(шаблоне) подциклом выводить книги данной серии.
Ответ написан
Ваш ответ на вопрос

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

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