У меня есть повторяющаяся проблема, которую я, похоже, не могу решить адекватно. Мой сайт сродни рабочему месту, где люди могут размещать задания (и детали внутри), а другие могут добавлять закладки в tthem. Очевидно, что каждая работа может быть отмечена более чем одним зрителем.Лучший способ показать данные из нескольких таблиц
Так вот model.py:
class Job(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=150)
description = models.CharField(max_length=5000)
class Bookmark(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
job = models.ForeignKey(Job, on_delete=models.CASCADE)
Мое намерение состоит в том, чтобы отобразить все задания на домашней странице, это означает, что несколько заданий от нескольких пользователей. Другие пользователи могут щелкнуть по иконке маленькой закладки, чтобы добавить ее в закладки, или не открывать ее. Как так:
Вот view.py:
def index(request):
context = {}
populateContext(request, context)
jobs = Job.objects.all().order_by('-id')
context = {'jobs': jobs}
return render(request, 'templates/index.html', context)
Довольно просто я думаю, что мое намерение. Вот как выглядит шаблон:
{% for job in jobs %}
<div>
{{ job.title }}<br>
{{ job.description }}<br>
by {{ job.user.username }}
</div>
{% endfor %}
Мой вопрос: как я могу отображать состояние закладки для каждого пользователя? Вот мое текущее решение:
{% for job in jobs %}
<div>
{{ job.title }}<br>
{{ job.description }}<br>
by {{ job.user.username }}<br>
{% for watch in job.bookmark_set.all %}
{% if watch.user_id = request.user.id %}
You have bookmarked this! <a>Unbookmark!</a>
{% endif %}
{% endfor %}
<a>Bookmark</a>
</div>
{% endfor %}
«Unbookmark!» Кстати, ссылка будет размещена по ссылке «Закладка». Решение выше работает так, потому что в таблице закладок будет содержаться нуль или более закладок для определенного задания, но у нескольких пользователей. Я бы обработал это в view.py, путем фильтрации только заданий, которые сделал пользователь, зарегистрированный в системе. Но я не могу отфильтровать, с какой задачей конкретно, потому что index.html будет отображать их все. Так, например, я мог бы плюнуть на это ...:
bookmarked = Bookmark.objects.all().filter(user_id=request.user.id)
... и что список будет все закладки на различных рабочих мест, что зарегистрированный пользователь сделал. Мне все равно нужно отфильтровать это в шаблоне, чтобы каждый проект соответствовал каждой закладке, и я понимаю, что это невозможно.
В любом случае, я думаю, что это довольно неэффективно. Поэтому мне было интересно, есть ли более простой способ справиться с этим? Предпочтительно, чтобы он работал следующим образом:
{% for job in jobs %}
<div>
{{ job.title }}<br>
{{ job.description }}<br>
by {{ job.user.username }}<br>
{% if job.id = bookmark.job.id %}
You have bookmarked this! <a>Unbookmark!</a>
{% else %}
<a>Bookmark</a>
{% endif %}
</div>
{% endfor %}
Спасибо!
Элегантное решение! – gglasses
Большое спасибо за подробное решение и объяснение! Второй подход работает отлично. Тем не менее, первый не делает. Если задание было занесено в закладки, оно дважды отображает задание (один раз, как не закладок, и еще раз как закладок). Кроме того, существует ли разница в скорости между обоими подходами? – Bob
Хмм, позвольте мне попробовать и исправить первый подход, чтобы он работал ... он более эффективен, так как он требует только запроса БД и фильтрации списка. – solarissmoke