value gets submitted through form, then even after the value got submitted and gets displayed, in a form the value got submitted is shown - javascript

Sorry for the long title, but this is what happens:
I submit word "hello", then hello gets displayed. Then in a form, it still says "hello". I'm not sure why this is happening. Is this django problem or some javascript code is needed for this...?Here's my full code I think is causing this problem.
in my views.py
def post(request, slug):
user = get_object_or_404(User,username__iexact=request.user)
try:
profile = MyProfile.objects.get(user_id=request.user.id)
# if it's a OneToOne field, you can do:
# profile = request.user.myprofile
except MyProfile.DoesNotExist:
profile = None
post = get_object_or_404(Post, slug=slug)
post.views += 1 # increment the number of views
post.save() # and save it
path = request.get_full_path()
comments = Comment.objects.filter(path=path)
#comments = post.comment_set.all()
comment_form = CommentForm(request.POST or None)
if comment_form.is_valid():
parent_id = request.POST.get('parent_id')
parent_comment = None
if parent_id is not None:
try:
parent_comment = Comment.objects.get(id=parent_id)
except:
parent_comment = None
comment_text = comment_form.cleaned_data['comment']
new_comment = Comment.objects.create_comment(
user=MyProfile.objects.get(user=request.user),
path=request.get_full_path(),
text=comment_text,
post = post,
parent = parent_comment)
for c in comments:
c.get_children()
context_dict = {
'post' :post,
'profile' :profile,
'comments' : comments,
'comment_form':comment_form
}
return render(request, 'main/post.html', context_dict)
and in my post.html I have
<table class='table'>
{% for comment in comments %}
<tr><td>{{ comment.get_comment }}
<br/><small>via {{ comment.user }} | {{ comment.timestamp|timesince }} ago </small>
{% if not comment.is_child %}
<ul>
{% for child in comment.get_children %}
<li>{{ child.get_comment }}
<small>via {{ child.user }}</small>
</li>
{% endfor %}
</ul>
<a href='#' class='reply_btn'>Reply</a>
<div class='reply_comment'>
<form method="POST" action=''>{% csrf_token %}
<input type='hidden' name='parent_id' value='{{ comment.id }}' />
{{ comment_form.as_p }}
<input type='submit' class='btn btn-default' value='Add reply'/>
</form>
</div>
{% endif %}
</td></tr>
{% endfor %}
</table>
</div>
<div class = "col-sm-3">
</div>
{% include 'footer.html' %}
<script>
{% block jquery %}
$('.reply_btn').click(function(e){
e.preventDefault();
$(this).next(".reply_comment").fadeToggle();
// $(".reply_comment").fadeToggle();
})
{% endblock %}
</script>
{% endblock %}
Can someone please direct me where I should look.....thank you

Before you check if a form is valid or not you assign the form to include the POST data so it will still include this when you return back to the form (in case it needs to show errors). The easiest fix would be to reassign the form after your valid logic is done.
comment_form = CommentForm(request.POST or None)
if comment_form.is_valid():
.. Valid logic ..
comment_form = CommentForm()

Related

When using Fetch the page reloads (when it shouldn't) and only shows the Json data instead of the page that should be displayed

I am trying to make a basic twitter style application for a class project. When the like button is clicked the text in the button should then change to say unlike and the like count should increase by one without reloading the page. The database information is updated. The page itself reloads to a white background and the only thing on the page is my json data "{"likeButton": "Unlike", "total_likes": 0}", instead of the page itself. Any help would be appreciated.
Edit: here is a screenshot of the result I am getting
webpage screenshot
views.py
#login_required
def likes(request, post_id):
try:
current_user = request.user
post = Post.objects.get(id = post_id)
likeCount = Post.objects.get(id = post.id)
total_likes = likeCount.like_count
likeButton = request.POST.get('buttonForLikes')
if likeButton == 'Like':
total_likes = total_likes + 1
post.like_count = total_likes
post.save()
post.like.add(current_user)
post.save()
else:
total_likes = total_likes - 1
post.like_count = total_likes
post.like.remove(current_user)
post.save()
return JsonResponse ({'likeButton': likeButton, 'total_likes': total_likes,}, status=200,)
except KeyError:
return HttpResponseBadRequest("Like Error")
urls.py
from django.urls import path
from . import views
app_name = "network"
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("new-post", views.new_post, name="new-post"),
path("profile/<str:username>", views.profile, name="profile"),
path("follows/<str:username>", views.follows, name="follows"),
path("following", views.following, name="following"),
path("edit", views.edit, name="edit"),
path("likes/<int:post_id>", views.likes, name='likes')
]
HTML
{% extends "network/layout.html" %}
{% load static %}
{% block body %}
{% if user.is_authenticated %}
<div class="borderDiv">
<div class="newPostCard">
<form id = "new_post_form" name="newPost" action = "{% url 'network:new-post' %}" method ="POST">
{% csrf_token %}
<label id="test"><h2>New Post</h2></label><br>
<textarea id="newPostBox" name="newPost"></textarea></textarea><br><br>
<input type ="submit" id = "new_post_submit" class = "btn btn-primary">
</form>
</div>
</div>
{% endif %}
<div class="newPostCard">
{% for item in all_post %}
<div class="borderDiv">
<div class="newPostCard">
<h2>{{ item.user }}</h2>
<p id="user_post">{{ item.post }}</p>
</div>
<form id = "like_form" method ="POST" action = "{% url 'network:likes' item.id %}" >
{% if request.user in item.like.all %}
<div> <button claas="likes" id = 'likeButton' data-id= '{{ item.id }}' value="Unlike" name="buttonForLikes">
Unike</button>: <span id="numOfLikes">{{ item.like_count }}</span>
{% csrf_token %}
</div>
{% else %}
<div> <button class="likes" id = 'likeButton' data-id= '{{ item.id }}' value="Like" name="buttonForLikes">
Like</button>: <span id="numOfLikes">{{ item.like_count }}</span>
{% csrf_token %}
</div>
{% endif %}
</form>
<div>
{% if user.is_authenticated and request.user == item.user %}
<button class ="btn btn-primary" id="edit">Edit</button>
{% endif %}
<textarea id="editText" name="editBox" style="display: none;"></textarea>
<button class="btn btn-primary" id="editSaveButton" style="display: none;">Save</button>
</div>
<p><i>{{ item.timestamp }}</i></p>
</div>
</div>
{% endfor %}
<div id="page_num">
<span class="page_numbers">
{% if all_post.has_previous %}
« first
previous
{% endif %}
<span class="current_page">
Page {{ all_post.number }} of {{ all_post.paginator.num_pages }}.
</span>
{% if all_post.has_next %}
next
last »
{% endif %}
</span>
</div>
</div>
<script src="{% static 'network/edit.js' %}"></script>
<script src="{% static 'network/likes.js' %}"></script>
{% endblock %}
javascript
let likes = document.getElementById('likeButton');
likes.addEventListener("click", (e) =>{
e.preventDefault();
e.stopPropagation();
let likeCount = document.getElementById('numOfLikes');
fetch(`/likes/${likes.dataset.id}`, {
credentials: "include",
method: "PUT",
headers: {
"Accept": "application/json",
'Content-Type': 'application/json',
},
})
.then(response => response.text())
.then(result => {
if (result.likeButton === 'Like'){
likes.innerHTML = "Unlike";
likeCount.innerHTML = result.total_likes;
}
else{
likes.innerHTML = 'Like';
likeCount.innerHTML = result.total_likes;
}
})
return false;
});

Django: Javascript error with alert box displaying values

I am creating a web application that will serve as a grocery store. The way I set it up is so the customer can come onto the website, click on the items that they would like to purchase, and then click a submit button to purchase those items. The problem I am running into is that my Javascript is not printing the correct values. In both spots, it says undefined. I will put a picture below for reference.
views.py
def inventory(request):
products = request.POST.getlist('products')
for product in products:
a = Post.objects.get(title=product)
a.quantity = a.quantity -1
a.save()
print(products)
return redirect('blog-home')
home.html
{% extends "blog/base.html" %}
{% load static %}
{% block content %}
<form action="{% url 'js' %}" method="POST" id="menuForm">
{% for post in posts %}
{% if post.quantity > 0 %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2">{{ post.category }}</a>
</div>
<h2><a class="article-title" >{{ post.title }}</a></h2>
<p class="article-content"> Price: ${{ post.Price }}</p>
<p class="article-content"> Sale: ${{ post.Sale }}</p>
<input type="checkbox" id="product_{{ post.id }}" value="{{ post.title }}" form="menuForm" name="products" > Inventory count: {{ post.quantity }}
</input>
</div>
</article>
{% else %}
{% endif %}
{% endfor %}
<button id="btn" type="submit" form="menuForm">Confirm Purchase</button>
</form>
<script src="{% static "JS/javascript.js" %}" type="text/javascript"></script>
{% endblock content %}
javascript.js
function getSelectedCheckboxValues(name) {
const checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
let values = [];
checkboxes.forEach((checkbox) => {
values.push(checkbox.value);
});
return values, tPrice;
var price = 0;
var tPrice =0;
if (values=='Milk'){
var MPrice = 3.99
tPrice = price+MPrice;
}
if (values == 'Cheese'){
var CPrice = 4.50
tPrice = price + CPrice;
}
if (values == 'Yogurt'){
var YPrice = 1.99
tPrice = price + YPrice;
}
}
const btn = document.querySelector('#btn');
btn.addEventListener('click', (event) => {
alert('You ordered: ' + getSelectedCheckboxValues('products')+
'\nTotal Price: $'+ getSelectedCheckboxValues('tPrice'));
});
First of all you are passing the parameter to the function getSelectedCheckboxValues as a string when you call them in the alert which is completely wrong.
Also you are directly comparing values list with strings which is not possible. You need to loop over the list and then compare the different elements with the different products. I will also recommend to create an object instead of the list and keep the product name as key and its price as value.

How can I use Ajax to display if username is already taken in django?

I'm trying to implement some code that will search if a username already exists and then display an error if it does dynamically rather than having to refresh the entire page. I tried implementing some JS and Ajax, but since I'm totally new to JS, it's not working and I'm not sure why. What am I doing wrong?
reg.html
{% extends "dating_app/base.html" %}
{% load bootstrap4 %}
{% block content %}
{% block javascript %}
<script>
$("#id_username").change(function () {
var username = $(this).val();
$.ajax({
url: '/ajax/check_if_username_exists_view/',
data: {
'username': username
},
dataType: 'json',
success: function (data) {
if (data.is_taken) {
alert("A user with this username already exists.");
}
}
});
});
</script>
{% endblock %}
<br>
<h1 class="text-center" style="color:#f5387ae6">Register to fall in love today!</h1>
<form method="post" style="width:700px;margin:auto" action="{% url 'dating_app:register' %}" enctype="multipart/form-data" class= "form" >
<div class="is-valid">
{% bootstrap_form registration_form%}
</div>
{% csrf_token %}
{% for field in bootstrap_form %}
<p>
{{field.label_tag}}
{{field}}
{% if field.help_text %}
<small style="color:grey;">{{field.help_text}}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red;">{{error}}"</p>
{% endfor %}
</p>
{% endfor %}
<div class="form-check">
<input type="checkbox" id="accept-terms" class="form-check-input">
<label for="accept-terms" class="form-check-label">Accept Terms & Conditions</label>
</div>
<div>
<br>
<button type="submit">Register</button>
</div>
</form>
{% endblock content %}
views.py/
def check_if_username_exists_view(request):
username = request.GET.get('username', None)
data = {
'is_taken': User.objects.filter(username__iexact=username).exists()
}
return JsonResponse(data)
urls.py/
path('ajax/check_if_username_exists_view/', views.check_if_username_exists_view, name='check_if_username_exists_view'),
models.py/
Class ProfileManager(BaseUserManager):
def create_user(self, username, email,description,photo, password=None):
if not email:
raise ValueError("You must creat an email")
if not username:
raise ValueError("You must create a username!")
if not description:
raise ValueError("You must write a description")
if not photo:
raise ValueError("You must upload a photo")
user = self.model(
email=self.normalize_email(email),
username = username,
description= description,
photo= photo,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, email,description,photo, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
description=description,
photo=photo,
)
user.is_admin=True
user.is_staff=True
user.is_superuser=True
user.save(using=self._db)
return user
class Profile(AbstractBaseUser):
class Meta:
swappable = 'AUTH_USER_MODEL'
email = models.EmailField(verbose_name="email")
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
#what I added
description = models.TextField()
photo = models.ImageField(upload_to='profile_photo',blank=False, height_field=None, width_field=None, max_length=100)
matches = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='+', blank=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['description','photo','email']
objects = ProfileManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self,app_label):
return True
So, in my base.html, which registration.html is inheriting from, I had 2 lines at the bottom of that page that were javascript lines that were not allowing Ajax to work because they were overriding the code I had in my registration.html. Once I removed them they started working.
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery-slim.min.js"><\/script>')</script>

Why is my Javascript not working for checking is Username already exists?

I am super new to Javascript, and I'm trying to implement some code that will search if a username already exists and then display an error if it does dynamically rather than having to hit submit and then finding out the username already existed. I tried implementing some JS but it's not working. What am I doing wrong?
reg.html
{% extends "dating_app/base.html" %}
{% load bootstrap4 %}
{% block content %}
{% block javascript %}
<script>
$("#id_username").change(function () {
var username = $(this).val();
$.ajax({
url: '/ajax/check_if_username_exists_view/',
data: {
'username': username
},
dataType: 'json',
success: function (data) {
if (data.is_taken) {
alert("A user with this username already exists.");
}
}
});
});
</script>
{% endblock %}
<br>
<h1 class="text-center" style="color:#f5387ae6">Register to fall in love today!</h1>
<form method="post" style="width:700px;margin:auto" action="{% url 'dating_app:register' %}" enctype="multipart/form-data" class= "form" >
<div class="is-valid">
{% bootstrap_form registration_form%}
</div>
{% csrf_token %}
{% for field in bootstrap_form %}
<p>
{{field.label_tag}}
{{field}}
{% if field.help_text %}
<small style="color:grey;">{{field.help_text}}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red;">{{error}}"</p>
{% endfor %}
</p>
{% endfor %}
<div class="form-check">
<input type="checkbox" id="accept-terms" class="form-check-input">
<label for="accept-terms" class="form-check-label">Accept Terms & Conditions</label>
</div>
<div>
<br>
<button type="submit">Register</button>
</div>
</form>
{% endblock content %}
views.py/check_if_username_exists_view
def check_if_username_exists_view(request):
username = request.GET.get('username', None)
data = {
'is_taken': User.objects.filter(username__iexact=username).exists()
}
return JsonResponse(data)
urls.py/check_if_username_exists_view
path('ajax/check_if_username_exists_view/', views.check_if_username_exists_view, name='check_if_username_exists_view'),
models.py
Class ProfileManager(BaseUserManager):
def create_user(self, username, email,description,photo, password=None):
if not email:
raise ValueError("You must creat an email")
if not username:
raise ValueError("You must create a username!")
if not description:
raise ValueError("You must write a description")
if not photo:
raise ValueError("You must upload a photo")
user = self.model(
email=self.normalize_email(email),
username = username,
description= description,
photo= photo,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, email,description,photo, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
description=description,
photo=photo,
)
user.is_admin=True
user.is_staff=True
user.is_superuser=True
user.save(using=self._db)
return user
class Profile(AbstractBaseUser):
class Meta:
swappable = 'AUTH_USER_MODEL'
email = models.EmailField(verbose_name="email")
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
#what I added
description = models.TextField()
photo = models.ImageField(upload_to='profile_photo',blank=False, height_field=None, width_field=None, max_length=100)
matches = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='+', blank=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['description','photo','email']
objects = ProfileManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self,app_label):
return True

Requesting Django server using ajax

my views.py -
def wall(request):
if request.method == 'POST':
post = request.POST
if 'logout' in post:
del request.session['username']
return redirect('home')
elif 'post' in post:
if post['post_text'] and not post['post_text'].isspace():
posted_by = request.session.get('username', '')
post_content = post['post_text']
post_id = posted_by+''+datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")
p = user_post(posted_by = posted_by, post_content = post_content, post_id = post_id)
p.save()
return redirect('wall')
else:
return redirect('error')
elif 'search_user' in post:
return redirect('search_user')
elif 'profile' in post:
return redirect('profile')
else:
if 'username' in request.session:
posts = user_post.objects.order_by('id')[:20].reverse()
return render(request, 'wall/wall_page.html', {'posts': posts, 'user': request.session['username']})
else:
return redirect('error')
template -
<div class="row" id="posts">
{% if posts %}
{% for post in posts %}
{% if user == post.posted_by %}
<p class="lead text-success text-right">
{{ post.post_content }}
<small>
<small>
<small>
<small>
{{ post.posted_by }}
</small>
</small>
</small>
</small>
</p>
{% else %}
<p class="lead text-info text-left">
{{ post.post_content }}
<small>
<small>
<small>
<small>
{{ post.posted_by }}
</small>
</small>
</small>
</small>
</p>
{% endif %}
{% endfor %}
{% endif %}
</div>
and related js file -
$(document).ready(function()
{
setInterval(function()
{
$.ajax(
{
type : "GET",
url : "http://10.8.21.17:8000/wall/wall",
}).done(function()
{
$('#posts').html();
});
}, 3000);
});
There is proper GET request to the server but the page is not reloading...i.e. when a user post something it is actually not showing to other users even if there is a GET request every 3 second. I copy-pasted the js code and dont know if it is correct. Anyone help me please. What i want to do is that the page should reload with the help of js so that user dont have to refresh.
Thanks in advance.
You're not doing anything with the response from the server in your JS. You need to actually use it:
.done(function(data)
{
$('#posts').html(data);
});

Categories