This is the first post of Qiita to commemorate.
I'm a person who loves Twitter, but I don't touch Twitter during work. So, I started to make a Twitter-like app for writing thoughts and memos, but it is quite difficult to implement a like button. .. .. If you do it with form, the feeling of Twitter will be weakened with page transitions, so I searched for other methods. At that time, I learned about Ajax and managed to implement it, so I decided to post it.
I have just started studying web frameworks and DBs, so if you have any mistakes, I would appreciate it if you could teach me.
Please note that this time we will omit the explanation of the part where the data input from the form is saved in the DB.
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.timeline, name='index'),
path('like/', views.like, name='like'),
]
Routing settings. Set the page that returns httpresponse.
models.py
from django.db import models
from django.utils import timezone
class PostTweet(models.Model):
memo = models.TextField(max_length=140)
published = models.DateTimeField(default=timezone.now)
star = models.BooleanField(default=False)
In models.py, in addition to the contents of the memo, define a Boolean value that indicates the "like" status.
forms.py
class PostForm(forms.ModelForm):
class Meta:
model = PostTweet
fields = ['memo', 'published', 'star']
forms.py looks like this. There is nothing special to mention, but I will post it for the time being.
views.py
from django.http import HttpResponse
from django.shortcuts import render
from .models import PostTweet
from .forms import PostForm, SearchForm
def index(request):
posts = PostTweet.objects.all().order_by('-published')
form = PostForm()
d = {
'form': form,
'posts': posts
}
return render(request, 'index.html', d)
def like(request):
if request.method == 'GET':
if 'star' in request.GET:
like = PostTweet.objects.get(id=int(request.GET['star']))
like.star = not like.star
like.save()
return HttpResponse('OK')
else:
return HttpResponse("NG")
I'll talk about like () later.
index.html
{% extends 'base.html' %}
{% block body %}
{% for post in posts %}
{{ post.memo | linebreaker }}
<br>
{% if post.star == False %}
<input type="checkbox" class="like" id="like_{{ post.id }}"
data_id="{{ post.id }}">
{% else %}
<input type="checkbox" class="like" checked="checked" id="like_{{ post.id }}"
data_id="{{ post.id }}">
{% endif %}
<label for="like_{{ post.id }}" class="like_label">★</label>
<script src="https://code.jquery.com/jquery-3.5.0.js"
integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc="
crossorigin="anonymous"></script>
<script type="text/javascript">
$('.like').click(function(){
var id;
id = $(this).attr("data_id");
$.ajax(
{
type:"GET",
url: "like",
data:{
star: id
}
})
});
</script>
{% endblock %}
I decided to use checkboxes and labels to represent the like button. If the star that represents the like status is True, set the checkbox to checked in advance.
Omitted for base.html.
style.css
.like{
display: none;
}
.like_label{
margin-left: 10px;
cursor: pointer;
color: #cccccc;
border: none; /*Erase the border*/
outline: none; /*Remove the border that appears when you click*/
background: transparent; /*Erase the gray background*/
}
input:checked + .like_label{
color: gold;
}
Turn off the button and show only the label. The default button label color should be gray. If the checkbox is checked, change the color of the button label to gold.
This will change the color each time you press the button.
Import jQuery. Use Ajax (asynchronous processing of javascript) to return the record id of the pressed button to the like method of views.py. (The id is automatically added when it is added to the DB.) Then, in views.py like (), set the star of the acquired id to not star and update it.
By doing this, the contents of the DB will be updated each time you press the button.
By using Ajax and checkboxes, I was able to implement a nice like button. Since this app is based on the premise that only you can see it, you can only turn it on and off, but I think you can make a type that counts the number of likes in the same way.
Thank you for reading this far!
Recommended Posts