Django представление в массиве
У меня есть 2 таблицы (posts, upvoted), в которых я работаю, и я хочу посмотреть, было ли сообщение уже проголосовано, и если да, то заменить стрелку upvote на заполненную стрелку. В моем представлении я уже передаю объект Upvote в мой шаблон и пытаюсь проверить, существует ли post.id в таблице upvoted. Я попробовал код ниже, но он не сработал. Как мне это сделать?
Модель:
class Post(models.Model):
user = models.ForeignKey(User, related_name="posts", on_delete=models.DO_NOTHING)
body = models.CharField(max_length=255)
image = models.ImageField(
default="onebyone.png", upload_to="images/", blank=True, null=True
)
created_at = models.DateTimeField(auto_now_add=True)
post_karma = models.IntegerField(default=0, blank=True, null=True)
comment_count = models.IntegerField(default=0, blank=True, null=True)
def __str__(self):
return f"{self.user.username} - {self.created_at.strftime('%Y-%m-%d')} - {self.body[:30]}"
class Upvoted(models.Model):
user = models.ForeignKey(User, related_name="upvoted", on_delete=models.CASCADE)
post = models.ForeignKey(Post, related_name="upvoted", on_delete=models.CASCADE)
upvoted_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return (
f"{self.user.username} - {self.post.user.username} - {self.post.body[:30]}")
Вид:
@login_required
def dashboard(request):
# form = PostForm(request.POST or None)
# if request.method == "POST":
form = PostForm(request.POST, request.FILES)
if form.is_valid():
img = form.cleaned_data["image"]
body = form.cleaned_data["body"]
if img is None:
img = "images/onebyone.png"
post = Post.objects.create(user=request.user, image=img, body=body)
post.save()
return redirect("posty:dashboard")
sorting = request.GET.get("sort")
ordering = {
"date_sort": "-created_at",
"karma_sort": "-post_karma",
"comment_sort": "-comment_count",
None: "-created_at",
}
# followed_posts = Post.objects.filter(
# user__profile__in=request.user.profile.follows.all()
# ).order_by("-created_at")
followed_posts = Post.objects.filter(
user__profile__in=request.user.profile.follows.all()
).order_by(ordering[sorting])
# get current date_time
now = datetime.now()
return render(
request,
"posty/dashboard.html",
{"form": form, "posts": followed_posts, "comment": Comment, "now": now, "upvote" : Upvoted, "downvote" : Downvoted},)
{% if post.id in upvote.post_id.all %}
Во-первых, не отправляйте объекты Модели в контекст, вы должны выполнять запросы в представлении, а затем отправлять результаты в контекст.
Второе:
Для этого можно использовать annotate()
и Exists()
.
from django.db.models import Exists, OuterRef
followed_posts = (
Post.objects.filter(
user__profile__in=request.user.profile.follows.all()
)
.annotate(
is_liked_by_user=Exists(
Upvoted.objects.filter(post_id=OuterRef('pk'), user=request.user)
)
)
.order_by(ordering[sorting])
)
Затем в вашем шаблоне:
{% if post.is_liked_by_user %}
... put whatever you want here.
{% endif %}