N
N
NerVik2016-04-03 09:46:50
Django
NerVik, 2016-04-03 09:46:50

How to get rid of duplicate information in django?

there is a model like this:

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)

those. as everyone knows, there are many types of one book, in different languages, with different translators, etc., for example, on goodreads: https://www.goodreads.com/book/show/3 and https://www.goodreads.com/ book/show/43507 there is only one book, there are differences in the description, the presence of an interpreter, etc.
problem: using the BookSummary model, you need to solve a similar problem: to reduce information about all the same books on one page.
problem: with such a view
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

everything is well displayed, what is needed, i.e. on the aggregator page of all books, all series to which all versions of this book belong are displayed. BUT the problem is that the same series are also displayed. those. if there is information about 3 versions of the book on the page and they all belong to a certain series, then this series will be displayed on the page three times, but you need it only once, because everything matches there. distinct() does not help here, as I understand it, because of the book field in the BookSeries model, you cannot delete it. How to solve the problem with this duplicate information?
I tried it in the view like this:
context['series'] = Series.objects.filter(book__summary=self.object).distinct()

this also displays what is needed without duplicates, but then it is not possible to access the position field from the BookSeries model from the BookSummary page

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
NerVik, 2016-04-05
@NerVik

I solved the problem, albeit in a way that I didn't like very much. I don't feel satisfied with it ;)
up to this point, the dev version was in SQLite, for the sake of convenience. I had to switch to PostgreSQL for the improved .distinct().
now the view looks like this:

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

A
Alexander, 2016-04-03
@syschel

If all books are tied to series, and all series are unique (no duplicates). Then it is necessary to display the series. And already in the template (template) to display the books of this series as a subcycle.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question