как перемешать данные, извлеченные из базы данных - PullRequest
0 голосов
/ 07 марта 2019

У меня есть шаблон книги, который отображает дополнительную информацию о книге, такую ​​как название, цена, автор и т. Д.

в том же шаблоне у меня есть аналогичный раздел книг, где я хочу отобразить книгу, аналогичную избранной книге в соответствии с классификацией (обе имеют одинаковую классификацию)

и для этого я думаю о том, чтобы перетасовать книги, которые я извлекаю из базы данных, вместо того, чтобы просто использовать обычный цикл, чтобы сделать его более динамичным, поскольку в каждой книге есть такая классификация, на странице каждый раз отображаются разные книги, а не одни и те же

вот код в views.py

def book(request, book_id):
book = get_object_or_404(Book, pk=book_id)
similar_books = Book.objects.all()[:4]

book_context = {
    'book': book,
    'similar_books': similar_books
}
return render(request, 'books/book.html', book_context)

и этот код в моем шаблоне

<div class="row">
            <div class="col py-5 text-center">
                <h3 class="mb-5">Similar books</h3>
                <div class="row d-flex justify-content-center">
                    {% for similar_book in similar_books %}
                        {% if similar_book.classification == book.classification and similar_book.id > book.id %}
                            <div class="col-md-3">
                                <a href="{% url 'book' similar_book.id %}"><img src="{{ similar_book.img.url }}"></a>
                                <a href="{% url 'book' similar_book.id %}"><p class="mt-2">{{ similar_book.title}}</p></a>
                                <p class="text-muted">{{ similar_book.author }}</p>
                                <p>{{ similar_book.price }}</p>
                            </div>
                        {% endif %}
                    {% endfor %}
                </div>
            </div>

причина, по которой я включаю similar_book.id > book.id, заключается в том, что я не хочу, чтобы эта книга отображалась в похожих книгах

я знаю, что это не лучший способ сделать это с помощью логики, как если бы выбранная книга была последней книгой в списке, цикл остановится

Я также подумал о замене оператора if выше на

{% for similar_book in similar_books[{{ similar_book.id }} -1:] %} чтобы начать циклический просмотр книг после избранной книги и добавление оператора if {% if book.id == len(similar_books) %} затем {% similar_book.id == 1 %}

но не уверен, правильно ли это логично или нет, есть идеи?

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

Не вставляйте логику в шаблон, например, если вы не хотите показывать книгу, которую вы предлагаете, вы можете исключить ее из набора запросов, например, так:

def book(request, book_id):
    book = get_object_or_404(Book, pk=book_id)
    similar_books = Book.objects.all().exclude(pk=book_id)[:4]
    ...

Вы можете получить результаты в случайном порядке с помощью order_by('?'), поэтому в итоге это будет выглядеть так:

def book(request, book_id):
    book = get_object_or_404(Book, pk=book_id)
    similar_books = Book.objects.all().exclude(pk=book_id).order_by('?')[:4]
    ...

Обратите внимание, что order_by('?') может быть медленным. Вы можете прочитать о различных способах перетасовки здесь: Как получить случайную запись, используя ORM Джанго?

0 голосов
/ 07 марта 2019

В Django есть много похожих постов для случайного получения объектов, например, this .

Я предлагаю сделать суффикс по вашему мнению:

id_list = list(
    Book.objects.exclude(pk=book.pk).values_list('id', flat=True))

n = 2
rand_ids = random.sample(id_list, n)
similar_books = Book.objects.filter(id__in=rand_ids)
...