I have a function with multiple if else statements that I'm trying to simplify in Django
Is there a pattern or maybe a better modeling approach that I could use here?
The idea behind is to have a thumbs up, thumbs down behavior for each blog post
views.py
@login_required
def blog_post_vote(request, slug):
post = get_object_or_404(BlogPost, slug=slug)
if request.method == "POST":
vote = request.POST['vote']
has_user_voted = BlogPostUserVote.objects.filter(blog_post=post, user=request.user).count()
if has_user_voted == 0:
if vote == "yes":
user_vote_yes = BlogPostUserVote(blog_post=post, user=request.user, vote_yes=1)
user_vote_yes.save()
if vote == "no":
user_vote_no = BlogPostUserVote(blog_post=post, user=request.user, vote_no=1)
user_vote_no.save()
else:
has_user_voted_yes = BlogPostUserVote.objects.filter(blog_post=post, user=request.user, vote_yes=1).count()
has_user_voted_no = BlogPostUserVote.objects.filter(blog_post=post, user=request.user, vote_no=1).count()
if vote == "yes" and has_user_voted_yes == 0:
user_vote_yes = BlogPostUserVote(blog_post=post, user=request.user, vote_yes=1)
user_vote_yes.save()
BlogPostUserVote.objects.filter(blog_post=post, user=request.user, vote_no=1).delete()
if vote == "no" and has_user_voted_no == 0:
user_vote_no = BlogPostUserVote(blog_post=post, user=request.user, vote_no=1)
user_vote_no.save()
BlogPostUserVote.objects.filter(blog_post=post, user=request.user, vote_yes=1).delete()
return redirect(request.META['HTTP_REFERER'])
models.py
class BlogPost(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
image = models.ImageField(upload_to='images/', blank=True, null=True)
title = models.CharField(max_length=500)
# Slug = Short URL Label
slug = models.SlugField(unique=True)
content = models.TextField(null=True, blank=True)
publish_date = models.DateTimeField(
auto_now=False, auto_now_add=False, null=True, blank=True)
timestamp = models.DateTimeField(auto_now=True)
updated = models.DateTimeField(auto_now=True)
@property
def thumbs_up(self):
return BlogPostUserVote.objects.filter(blog_post=self).aggregate(Sum("vote_yes"))['vote_yes__sum']
@property
def thumbs_down(self):
return BlogPostUserVote.objects.filter(blog_post=self).aggregate(Sum("vote_no"))['vote_no__sum']
# This line is very important as it maps the objects to the default manager
objects = BlogPostManager()
# Ordering Newest to Oldest
class Meta:
ordering = ['-publish_date', '-updated', '-timestamp']
def get_absolute_url(self):
return f"/blog/{self.slug}"
class BlogPostUserVote(models.Model):
blog_post = models.ForeignKey(BlogPost, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
vote_yes = models.SmallIntegerField(null=True, blank=True)
vote_no = models.SmallIntegerField(null=True, blank=True)
has_user_voted
and friends? Reading the variable name, I would think a booleanTrue
/False
. But you keep checking if==0
instead. \$\endgroup\$