Django изменяет тег <a> в шаблоне в зависимости от условия
У меня есть посты с возможностью их сохранения. Представление работает правильно, но я не могу увидеть изменения в кнопке. Я хочу, чтобы когда пост не сохранен пользователем, кнопка говорила "Сохранить пост", а когда он уже сохранен, кнопка должна говорить "Отмена сохранения". С последней частью у меня возникают проблемы. Вот часть кода
views.py
def post(request):
posts = Post.objects.all().order_by("-date_created")
return render(request, "post/food-feed.html", {"posts": posts})
def save_post(request, pk):
post = get_object_or_404(Post, id=pk)
if post.favorite_posts.filter(id=request.user.id).exists():
post.favorite_posts.remove(request.user)
else:
post.favorite_posts.add(request.user)
return HttpResponseRedirect(request.META["HTTP_REFERER"])
шаблон
<a href="{% url 'save-post' post.id %}" class="btn btn-primary float-start">Save post</a>
urls.py
path("post/<int:pk>/save", views.save_post, name="save-post")
forms.py
class UserSignupForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ["username", "email", "password1", "password2"]
def clean_username(self):
username = self.cleaned_data["username"].lower()
if not re.match(r"^[A-Za-z0-9_]+$", username):
raise forms.ValidationError(
"Sorry, your username must only contain letters, numbers and underscores."
)
elif (
User.objects.exclude(pk=self.instance.pk).filter(username=username).exists()
):
raise forms.ValidationError(f"Username {username} is already in use.")
else:
return username
models.py
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=80)
slug = models.SlugField(max_length=250, null=True, blank=True)
post_description = models.TextField(max_length=140, null=True, blank=True)
date_created = models.DateTimeField(default=timezone.now)
date_updated = models.DateTimeField(auto_now=True)
main_image = models.ImageField(upload_to="post_pics")
is_recipe = models.BooleanField()
ingredients = models.TextField(blank=True, null=True)
recipe_description = models.TextField(blank=True, null=True)
cooking_time = models.CharField(max_length=20, blank=True, null=True)
likes = models.ManyToManyField(User, related_name="post_likes")
loves = models.ManyToManyField(User, related_name="post_loves")
drooling_faces = models.ManyToManyField(User, related_name="post_drooling_faces")
favorite_posts = models.ManyToManyField(
User, related_name="favorite_posts", default=None, blank=True
)
def clean(self, *args, **kwargs):
if (
(self.is_recipe and self.ingredients == None)
or (self.is_recipe and self.ingredients == None)
or (self.is_recipe and self.recipe_description == None)
or (self.is_recipe and self.cooking_time == None)
):
raise ValidationError("You need to complete the recipe fields!")
if not self.slug:
slug_title = slugify(self.title)
slug_date = slugify(self.date_created)
self.slug = f"{slug_title}-{slug_date}"
super().clean(*args, **kwargs)
class Meta:
ordering = ("-date_created",)
def save(self, *args, **kwargs):
self.full_clean()
return super().save(*args, **kwargs)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse("post-detail", kwargs={"slug": self.slug})
def like_count(self):
return self.likes.count()
def love_count(self):
return self.loves.count()
def droolingface_count(self):
return self.drooling_faces.count()
Каждый пост отображается в шаблоне feed-food с изображением пользователя, именем пользователя, датой, фотографией, заголовком, лайком, описанием и КНОПКОЙ СОХРАНИТЬ Что мне нужно добавить, чтобы утверждение работало?
Вы можете сделать это, используя анотацию queryset или пользовательский тег фильтра. Я не знаю ваших моделей. но вы можете аннотировать is_favorite примерно так в просмотре поста:
from django.db.models import Exists, OuterRef
Post.objects.annotate(
is_favorite=Exists(
Favorite.objects.filter(user=user, product_id=OuterRef('pk'))
)
)
в шаблоне:
{% if post.is_favorite %}
save
{% else %}
unsave
{% endif %}