Django UNIQUE constraint failed: core_organization.name - django

So I have a model called Organization inside core/models.py. I am trying to implement CRUD Ajax on a single page. Inspired by this post. Every time I save an object of this model I get this error as shown below. I want to have multiple organizations that are unique.
core/models.py
class Organization(models.Model):
name = models.CharField(max_length=255, unique=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
gstin = models.CharField(max_length=15)
address = models.CharField(max_length=500)
city = models.CharField(max_length=50)
state = models.CharField(max_length=50)
zipcode = models.CharField(max_length=6)
country = models.CharField(max_length=50)
is_billed = models.BooleanField(default=False)
def __str__(self):
return f'{self.name} Organization'
core/forms.py
class OrganizationForm(forms.ModelForm):
class Meta:
model = models.Organization
fields = ('name', 'address', 'state', 'city', 'zipcode', 'country', 'gstin')
core/views.py
def save_organization_form(request, form, template_name):
data = dict()
if request.method == 'POST':
if form.is_valid():
stock = form.save(commit=False)
stock.user = request.user
stock.save()
data['form_is_valid'] = True
organizations = Organization.objects.all()
data['html_book_list'] = render_to_string('core/includes/partial_organization_list.html', {
'organizations': organizations
})
else:
data['form_is_valid'] = False
context = {'form': form}
data['html_form'] = render_to_string(template_name, context, request=request)
return JsonResponse(data)
#login_required(login_url="/accounts/login/")
def organization_create(request):
if request.method == 'POST':
form = OrganizationForm(request.POST)
else:
form = OrganizationForm()
return save_organization_form(request, form, 'core/includes/partial_organization_create.html')
templates/base.html
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>{% block head_title %}{% endblock %}</title>
{% block extra_head %}
{% endblock %}
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link href='https://fonts.googleapis.com/css?family=Russo One' rel='stylesheet'>
<link rel="stylesheet" type="text/css" href="{% static 'font/flaticon.css' %}">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
{% block body %}
{% if messages %}
<div class="text-center">
<strong>Messages:</strong>
<ul>
{% for message in messages %}
<li>{{message}}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% block content %}
{% endblock %}
{% endblock %}
{% block extra_body %}
{% endblock %}
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
{% block javascript %}
{% endblock %}
</body>
</html>
templates/core/organization_list.html
{% extends 'base.html' %}
{% load static %}
{% block javascript %}
<script src="{% static 'organizations/js/organizations.js' %}"></script>
{% endblock %}
{% block content %}
<h1 class="page-header">Organizations</h1>
<!-- BUTTON TO TRIGGER THE ACTION -->
<p>
<button type="button"
class="btn btn-primary js-create-book"
data-url="{% url 'organization_create' %}">
<span class="glyphicon glyphicon-plus"></span>
New Organization
</button>
</p>
<table class="table" id="book-table">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Address</th>
<th>State</th>
<th>City</th>
<th>Zipcode</th>
<th>Country</th>
<th>Billing Active</th>
</tr>
</thead>
<tbody>
{% include 'core/includes/partial_organization_list.html' %}
</tbody>
</table>
<!-- THE MODAL WE WILL BE USING -->
<div class="modal fade" id="modal-book">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
{% endblock %}
templates/core/partial_organization_list.html
{% for organization in organizations %}
<tr>
<td>{{ organization.id }}</td>
<td>{{ organization.name }}</td>
<td>{{ organization.address }}</td>
<td>{{ organization.state }}</td>
<td>{{ organization.city }}</td>
<td>{{ organization.zipcode }}</td>
<td>{{ organization.country }}</td>
<td>{{ organization.is_billed }}</td>
<td>
<button type="button"
class="btn btn-warning btn-sm js-update-book"
data-url="{% url 'organization_update' organization.id %}">
<span class="glyphicon glyphicon-pencil"></span> Edit
</button>
<button type="button"
class="btn btn-danger btn-sm js-delete-book"
data-url="{% url 'organization_delete' organization.id %}">
<span class="glyphicon glyphicon-trash"></span> Delete
</button>
</td>
</tr>
{% empty %}
<tr>
<td colspan="8" class="text-center bg-warning">No Organization</td>
</tr>
{% endfor %}
static/organizations/js/organizations.js
$(function () {
$(".js-create-book").click(function () {
$.ajax({
url: '/profile/organization/create/',
type: 'get',
dataType: 'json',
beforeSend: function () {
$("#modal-book").modal("show");
},
success: function (data) {
$("#modal-book .modal-content").html(data.html_form);
}
});
});
});
$("#modal-book").on("submit", ".js-book-create-form", function () {
var form = $(this);
$.ajax({
url: form.attr("action"),
data: form.serialize(),
type: form.attr("method"),
dataType: 'json',
success: function (data) {
if (data.form_is_valid) {
$("#book-table tbody").html(data.html_book_list); // <-- Replace the table body
$("#modal-book").modal("hide"); // <-- Close the modal
}
else {
$("#modal-book .modal-content").html(data.html_form);
}
}
});
return false;
});
$(".js-create-book").click(function () {
var btn = $(this); // <-- HERE
$.ajax({
url: btn.attr("data-url"), // <-- AND HERE
type: 'get',
dataType: 'json',
beforeSend: function () {
$("#modal-book").modal("show");
},
success: function (data) {
$("#modal-book .modal-content").html(data.html_form);
}
});
});
$(function () {
/* Functions */
var loadForm = function () {
var btn = $(this);
$.ajax({
url: btn.attr("data-url"),
type: 'get',
dataType: 'json',
beforeSend: function () {
$("#modal-book").modal("show");
},
success: function (data) {
$("#modal-book .modal-content").html(data.html_form);
}
});
};
var saveForm = function () {
var form = $(this);
$.ajax({
url: form.attr("action"),
data: form.serialize(),
type: form.attr("method"),
dataType: 'json',
success: function (data) {
if (data.form_is_valid) {
$("#book-table tbody").html(data.html_book_list);
$("#modal-book").modal("hide");
}
else {
$("#modal-book .modal-content").html(data.html_form);
}
}
});
return false;
};
/* Binding */
// Create book
$(".js-create-book").click(loadForm);
$("#modal-book").on("submit", ".js-book-create-form", saveForm);
// Update book
$("#book-table").on("click", ".js-update-book", loadForm);
$("#modal-book").on("submit", ".js-book-update-form", saveForm);
// Delete book
$("#book-table").on("click", ".js-delete-book", loadForm);
$("#modal-book").on("submit", ".js-book-delete-form", saveForm);
});
And when I add a new organization I get the following error:
django.db.utils.IntegrityError: UNIQUE constraint failed: core_organization.name
How do I fix this?

I believe your javascript file contains duplicate ajax calls.
There are 3 calls to create your modal:
$(function () {
$(".js-create-book").click(function () {
at the top of your js file. Then the same function in the middle of your js file. And
var loadForm = function ()
which your binding to the click event at the bottom of your script.
In addition there are two functions handling the submission of the form data:
$("#modal-book").on("submit", ".js-book-create-form", function ()
in the top part and
var saveForm = function ()
in the bottom part.
The duplicate regarding the submission of the form can cause the unique constraint error because you are submitting the same data twice. The duplication of the loading of the modal probably does not cause any noticable errors, but is unnecessary load.
The bottom part of your javascript file, i.e. the part beginning with
$(function () {
/* Functions */
should be sufficient.

I think you are having this issue, because of the unique=True constraint on your name field
name = models.CharField(max_length=255, unique=True)
This means that the name is going to be unique for all users, and you will keep getting UNIQUE constraint failed error everytime you add the same name for different users.
To solve this, I suggest using unique_together meta option.
All you have to do, is removing the unique constraint from name field, and adding Meta class with the unique_toghether option to include both the user_id and name fields.
class Organization(models.Model):
name = models.CharField(max_length=255)
user = models.ForeignKey(User, on_delete=models.CASCADE)
address = models.CharField(max_length=1000, default=None)
is_billed = models.BooleanField(default=False)
def __str__(self):
return f'{self.name} Organization'
class Meta:
unique_together = ['name', 'user_id']
Then, python manage.py makemigrations, python manage.py migrate.
The UNIQUE constraint going to remain, but it is going to be for all Organization names related for one user.
If USER1 have organization ORG1, and tried to add another ORG1, it is going to fail, but if USER2 added ORG1 it is going to work successfully.

Try updating the instance rather than form object, Create separate endpoint/logic for updating instance and an separate endpoint/logic to create objects using form
views.py
def save_organization_form(request, form, template_name):
data = dict()
if request.method == 'POST':
if form.is_valid():
stock = form.instance
stock.user = request.user
stock.something = request.something
stock.save()
data['form_is_valid'] = True
organizations = Organization.objects.all()
data['html_book_list'] = render_to_string('core/includes/partial_organization_list.html', {
'organizations': organizations
})
else:
data['form_is_valid'] = False
context = {'form': form}
data['html_form'] = render_to_string(template_name, context, request=request)
return JsonResponse(data)
#login_required(login_url="/accounts/login/")
def organization_create(request):
if request.method == 'POST':
form = OrganizationForm(request.POST)
else:
form = OrganizationForm()
return save_organization_form(request, form, 'core/includes/partial_organization_create.html')

Related

Why Is Ajax Creating a New Comment When I'm Trying To Edit An Existing One?

I am trying to do a Django Blog in Class Based Views. They're proving very difficult to me anyway. I feel like I'm pretty close...I suspect it's creating a new one because I'm combining DetailView and trying to include an UpdateView in my page. I'm overriding POST on the DetailView...and perhaps that's why when I try to do my Update of the comment the overriden Post on DetailView is overriding that action?
Here's my code....
HTML...
<!DOCTYPE html>
<form method='POST' class="comment-form">
{% csrf_token %}
<div class="spacer284">
{{ form.comment }}
</div>
<button class="button7" type="submit">Submit</button>
</form>
<div class="spacer285">
{% include 'suggestion_comments.html' %}
</div>
</div>
{% endblock %}
Note that I'm doing an include so that I can loop through the comments more easily...
Here's the include template...
{% if suggestion_comments %}
<h2>Comments</h2>
{% for comment in object.suggestion_comments.all %}
<div class="spacer291">
<p>{{ comment.author }} {{ comment.created_on }}</p>
<p class="spacer290">{{ comment.comment }}</p>
<div class="spacer289">
<div class="upvote-comment-count">{{ comment.total_comment_upvotes }}</div>
<div class="hide-delete">
<button type="button" class="button6" data-href="{% url 'Suggestions:suggestion_comment_like' comment.id %}">Like</button>
</div>
<div class="hide-delete">
<button type="button" class="button2" data-href="">Reply</button>
</div>
{% if comment.author == request.user %}
<button type="button" class="button4" id="{{ comment.id }}" pk="{{ object.pk }}" href="{% url 'Suggestions:suggestion_comment_edit' object.pk comment.id %}">Edit</button>
<div class="spacer159" id="hide_payment" style="display:none;">
<input name="comment" id="commentInput" value="{{ comment.comment }}" class="name"/>
<button class="button7">Submit</button>
</div>
<div class="hide-delete">
{% if user.userprofile.eDirector_queue_delete_confirm == "Yes" %}
<button type="button" class="button5" data-href="{% url 'Suggestions:suggestion_delete' comment.id %}">Delete</button>
{% else %}
<button type="button" class="button3" data-href="{% url 'Suggestions:suggestion_delete' comment.id %}">Delete</button>
{% endif %}
</div>
{% endif %}
</div>
</div>
{% endfor %}
{% else %}
<h2>No Comments Yet</h2>
{% endif %}
I'm attempting to use AJAX to do a replace...
$(document).on('submit', '.comment-form', function(e) {
e.preventDefault();
var $this = $(this);
$.ajax({
type: "POST",
url: $this.data("href"),
data: $this.serialize(),
dataType: "json",
csrfmiddlewaretoken: "{{ csrf_token }}",
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
},
success: function(response){
console.log("so far");
$('.spacer285').html(response['form']);
$(".comment-form")[0].reset();
$('.spacer288').empty('spacer288');
},
error: function (request, status, error) {
console.log(request.responseText);
showAjaxFormErrors(JSON.parse(request.responseText));
},
});
});
$(document).on('click', '.button7', function(e) {
e.preventDefault();
console.log("working123");
var $this = $(this);
var comment = $('#commentInput').val();
console.log(comment);
$.ajax({
type: "POST",
url: $this.data("href"),
data: { comment: comment},
csrfmiddlewaretoken: "{{ csrf_token }}",
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
},
success: function(data){
console.log(data);
$('.comment-form1').html(data);
},
});
});
My DetailView...
class SuggestionDetailView(LoginRequiredMixin,DetailView):
model = Suggestion
context_object_name = 'suggestion_detail'
template_name = 'suggestion_detail.html'
def get_context_data(self, **kwargs):
context = super(SuggestionDetailView, self).get_context_data(**kwargs)
attachments = SuggestionFiles.objects.filter(suggestion=self.object.pk).all()
form = SuggestionCommentForm()
suggestion_comments = SuggestionComment.objects.filter(suggestion_id=self.object.pk).order_by('-created_on').all()
context['attachments'] = attachments
context['form'] = form
context['suggestion_comments'] = suggestion_comments
return context
def post(self, request, *args, **kwargs):
form = SuggestionCommentForm(request.POST)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.author = request.user
new_comment.suggestion = self.get_object()
new_comment.save()
self.object = self.get_object()
context = self.get_context_data(object=self.object)
html = render_to_string('suggestion_comments.html', context, request=self.request)
return JsonResponse({'form': html})
else:
form_errors = form.errors.as_json()
response = HttpResponse(form_errors, status=400)
response['content_type'] = 'application/json'
return response
MyCommentUpdateView...
class SuggestionCommentUpdateView(LoginRequiredMixin, UpdateView):
model = SuggestionComment
fields = ["comment"]
def form_valid(self, form):
form.instance.suggestion_id = self.kwargs["pk"]
return super().form_valid(form)
And my URLs...
path("a7900f81-b66a-41ea-afc2-d7735e6d4824/suggestion_detail/<uuid:pk>/suggestion_comment_edit/<int:id>",views.SuggestionCommentUpdateView.as_view(), name='suggestion_comment_edit'),
path("a7900f81-b66a-41ea-afc2-d7735e6d4824/suggestion_detail/<uuid:pk>/",views.SuggestionDetailView.as_view(), name='suggestion_detail'),
This is all almost working....My issue is when I click on the edit button and attempt to edit the comment....it works...and updates the database...but it's adding a new updated comment instead of just editing the existing comment. Thanks in advance for any thoughts on what I might be doing wrong.

Django - changing object value and displaying it without reloading

I got this model:
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
item = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.IntegerField()
and I'd like to make user able to change its quantity value without reloading page
tried to do it this way:
views:
def increaseQuantity(request):
if request.method == 'GET':
orderItem_id = request.GET['orderItem_id']
orderitem = OrderItem.objects.get(id=orderItem_id)
orderitem.quantity += 1
orderitem.save()
url
path('cart/increase/', increaseQuantity, name='increase'),
template:
{% for product in products %}
<div >Some button content</div>
{% endfor %}
#
#
#
$('.quantity-increase').click(function(){
var orderItemId;
orderItemId = $(this).attr("data-orderItemId");
$.ajax({
type: "GET",
url: "increase",
data:{
orderItem_id:orderItemId
},
})
})
Quantity is being increased correctly, but I need to reload page to see results. What should I add/change to be allowed to see them without reloading ?
view used to see results:
def cart(request):
data = cartData(request)
cartItems = data['cartItems']
order = data['order']
items = data['items']
context = {'items':items, 'order':order, 'cartItems':cartItems}
return render(request, 'store/cart.html', context)
template
{% for item in items %}
<div class="cart-row">
<div style="flex:2"><img class="row-image" src="{{ item.product.imageURL }}"></div>
<div style="flex:2">{{ item.product.name }}</div>
<div style="flex:1">${{ item.product.price|floatformat:2 }}</div>
<div style="flex:1">
<p class = "quantity">{{item.quantity}}</p>
<div class = "quantity">
<img data-product={{item.product.id}} data-action="add" class="chg-quantity update-cart" src="{% static 'images/arrow-up.png' %}">
<img data-product={{item.product.id}} data-action="remove" class="chg-quantity update-cart" src="{% static 'images/arrow-down.png' %}">
</div>
</div>
<div style="flex:1">${{ item.get_total }}</div>
</div>
{% endfor %}
POST method is more suitable for this request
view
from django.http import JsonResponse
def increaseQuantity(request):
if request.method == 'POST':
if request.POST.get("operation") == "increase":
orderitem = OrderItem.objects.get(id=request.POST.get('orderItem_id', None))
orderitem.quantity += 1
orderitem.save()
return JsonResponse({'count':orderitem.quantity)
return JsonResponse({'error':'error')
html
{% for product in products %}
<div >Some button content</div>
{% endfor %}
#
#
#
$('.quantity-increase').click(function(){
var orderItemId;
orderItemId = $(this).attr("data-orderItemId");
$.ajax({
type: "POST",
url: "increase",
data:{
orderItem_id:orderItemId,
csrfmiddlewaretoken: '{{ csrf_token }}',
'operation':'increase'
},
success: function(data) {
$('.count-of-item').html(data.count) // your results element to show current quantity
console.log(data.count)
},
})
})

asynchronus form submission django

I'm using ajax to submit a form, and it's working. But it's not working asynchronously. When I'm trying to upload files it uploaded successfully and then the page loads again. I want it to make asynchronously. In addition, I want to make a progress bar too. But things not working as I expected.
my forms.py
from django import forms
from .models import Comment
from .models import post
class UploadForm(forms.ModelForm):
class Meta:
model = post
fields = ('image', 'video', 'content',)
my views.py
def django_image_and_file_upload_ajax(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
form.instance.author = request.user
form.save()
return JsonResponse({'error': False, 'message': 'Uploaded Successfully'})
else:
return JsonResponse({'error': True, 'errors': form.errors})
else:
form = UploadForm()
return render(request, 'blog/upload.html', {'form': form})
and my upload.html
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<main>
<div class="container">
<div class="row">
<div class="col-md-8 my-5">
<div class="content-section" style="padding:10px 20px">
<form
enctype="multipart/form-data"
id="id_ajax_upload_form" method="POST"
novalidate="">
<fieldset class="form-group">
{% csrf_token %}
<legend class="border-bottom mb-4"><i class="fas fa-feather-alt text-muted mr-2"></i>Create a post</legend>
{{ form.as_p }}
</fieldset>
<div class="form-group">
<input type="submit" />
</div>
</form>
</div>
</div>
</div>
</div>
</main>
{% endblock content %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
// form upload
$('#id_ajax_upload_form').submit(function(e){
e.preventDefault();
$form = $(this)
var formData = new FormData(this);
$.ajax({
url: window.location.pathname,
type: 'POST',
data: formData,
success: function (response) {
$('.error').remove();
console.log(response)
if(response.error){
$.each(response.errors, function(name, error){
error = '<small class="text-muted error">' + error + '</small>'
$form.find('[name=' + name + ']').after(error);
})
}
else{
alert(response.message)
window.location = ""
}
},
cache: false,
contentType: false,
processData: false
});
});
// end
where i get wrong?
Ok, Got it! But anyone know about how to add a progressbar will be helpful.

django ajax like button with css classes

hello I have a post model which has a like(m2m) and user(forgeinkey) model field and Im trying to check if the request.user has liked the post and if they have, I should show them a red heart button else a blue heart should be shown, now since there are multiple posts and likes, Im looping through each like object to check if the request.user has liked it or not. Unfortunately for some reason, I couldn't implement a good logic and I see like button for every user. Some help would be appreciated.
Here's my model:
class post(models.Model):
user = models.ForeignKey(User,default='' , related_name='has_liked', on_delete=models.CASCADE)
caption = models.CharField(max_length=100)
image = models.FileField(upload_to='images/', null=True, blank=True)
video = models.FileField(upload_to='videos/', null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
like = models.ManyToManyField(User, null=True, blank=True, default='')
The View:
#login_required
def usersfeed(request):
users = User.objects.all()
posts = post.objects.filter(Q(user__in=request.user.profile.friend.all()) | Q(user=request.user)).order_by('-created')
comments = Comment.objects.all()
status_form = StatusForm(request.POST)
friend_requests = FriendRequest.objects.filter(to_user=request.user)
friends = request.user.profile.friend.all()
for i in posts:
likes = i.like.all()
print(likes)
for like in likes:
if like.username == request.user.username:
if request.user:
Hasliked = True
print('liked')
else:
Hasnotliked = True
print('not liked')
context = {
'Post':posts,
'User':users,
'form':PostForm(),
'Profile':profile,
'Form':CommentForm(),
'Comment':comments,
'Status':status_form,
'fr':friend_requests,
'friend':friends,
'Hasliked':Hasliked,
'Hasnotliked':Hasnotliked,
}
return render(request, 'social_media/feed.html', context=context)
The view for ajax like counter:
#login_required
def like_post(request):
Post = get_object_or_404(post, id=request.GET.get('post_id'))
cssClass = 'colorRed'
if Post.like.filter(id=request.user.id).exists():
Post.like.remove(request.user)
else:
Post.like.add(request.user)
count = Post.like.count()
users = Post.like.all()
user = []
for i in users:
user.append((i.username))
response = {
'count':count,
'users':user,
'cssClass':cssClass,
}
return JsonResponse(response)
The Html code:
{% for i in Post %}
<form action="{% url 'like_post' %}" class='like-submit' data-catid="{{ i.id }}" method="GET">
<div class="like">
{% if Hasliked == True %}
<button id="likeBtn{{ i.id }}" class="likeClassBtn colorRed">
<i class="fas fa-heart"></i>
</button>
{% endif %}
{% if Hasnotliked == True %}
<button id="likeBtn{{ i.id }}" class="likeClassBtn">
<i class="fas fa-heart"></i>
</button>
{% endif %}
<div class="show_likes">
<span id="likes_count{{ i.id }}">{{ i.total_likes }}</span>
<div class="username_liked">
<div id="user-likes{{ i.id }}" class="user-likes">
{% for p in i.like.all %}
{{ p.username }}
{% endfor %}
</div>
</div>
</div>
</div>
</form>
{% endfor %}
<script>
$(document).ready(function () {
$(".like-submit").submit(function (event) {
event.preventDefault()
const url = $(this).attr('action');
const catid = $(this).attr("data-catid");
$.ajax({
type: "GET",
url: url,
data: {
post_id: catid,
},
success: function (data) {
$('#likes_count' + catid).html(data.count)
if ($('#user-likes' + catid).html()){
$('#user-likes' + catid).html(data.users + ' ')
$('#likeBtn' + catid).toggleClass(data.cssClass)
}
}
});
});
});
</script>
you need to store the hasLiked/hasNotLiked in the post record for that user. The code above, implies that all posts are either liked or unliked. You also need to rethink the way you load your context- the current code is extremely inefficient. I would suggest to replace the Hasliked and Hasnotliked context entries with id arrays where each one will contains the ids of the posts that the current user liked/disliked. Then in the template do in check:
{% if i.id in Hasliked %}
<button id="likeBtn{{ i.id }}" class="likeClassBtn colorRed">
<i class="fas fa-heart"></i>
</button>
{% endif %}
{% if i.id in Hasnotliked %}
<button id="likeBtn{{ i.id }}" class="likeClassBtn">
<i class="fas fa-heart"></i>
</button>
{% endif %}
the hasliked, disliked can be loaded using your current setup:
friends = request.user.profile.friend.all()
for i in posts:
likes = i.like.all()
print(likes)
for like in likes:
if like.username == request.user.username:
if request.user:
Hasliked.append(i.id)
print('liked')
else:
Hasnotliked.append(i.id)
print('not liked')
This it would be extremely inefficient, the best way to si ur is to query the database directly, and simply returning the ids:
l_likedPosts = PostActions.objects.filter(user_id=l_currUser,
liked=True)
.values_list('post_id',flat=True)
Hasliked = list(l_likedPosts)
The code above assumes that you have a table PostActions that contains at least the user_id, the post_id and the liked/disliked status. This is generally what the manytomany field does for you, behind the scenes, but using it takes too much freedom in more complicated data models.

Post method in django using ajax

I have a form that I am trying to implement with Ajax, after inputing some content on the textbox, when I click on the sumbit button using my mouse, everything works fine (page didnt refresh, data posted on database, and new data displayed on the page). But when I try to submit data by pressing enter, the page is displaying only the serialized data from my form (nothing more, html file do not work)and it says in the console:
Resource interpreted as Document but transferred with MIME type application/json: "http://localhost:8000/try/".
current page looks exactly like this after pressing enter button(nothing more):
{"task": {"id": 52, "todo": "wws", "author": 1, "completed": false}}
these are the data that came from my form.
this is my views.py
class TodoList(View):
def get(self, request):
todo_list = ToDo.objects.filter(author_id=request.user.id)
form = AddTodo()
context = {
'todo_list': todo_list,
'form': form,
}
return render(request, 'trylangto/try.html', context)
def post(self, request):
form = AddTodo(request.POST)
if form.is_valid():
form.instance.author_id = request.user.id
new_form = form.save()
return JsonResponse({'task': model_to_dict(new_form)}, status=200)
else:
return redirect('trylang:todo-list')
return redirect('trylang:todo-list')
this is my main.js:
$(document).ready(function(){
$("#createbutton").click(function(){
var formdata = $("#addtodoform").serialize();
$.ajax({
url: $("#addtodoform").data('url'),
data: formdata,
type: 'post',
success: function(response){
$("#tasklist").append('<div class="card mb-1" ><div class="card-body">'+ response.task.todo +'<button type="button" class="close"><span aria-hidden="true">×</span></button></div></div>')
}
});
});
});
and here is my template:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block content %}
{% if user.is_authenticated %}
<div class="media content-section">
<form class="media-body pt-3" method="POST" id="addtodoform" data-url="{% url 'trylang:todo-list' %}">
{% csrf_token %}
<legend><h5>add new tasks</h5></legend>
<fieldset class="form-group ">
{{ form|crispy}}
</fieldset>
<button class="btn btn-outline-info float-right" type="button" id="createbutton">add</button>
</form>
</div>
{% endif %}
<div id="tasklist">
{% for task in todo_list %}
<div class="card mb-1" >
<div class="card-body">
{{task.todo}}
<button type="button" class="close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
UPDATE: I am including my models.py just in case
class ToDo(models.Model):
todo = models.CharField(max_length=500)
date_posted = models.DateTimeField(default=timezone.now, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='users')
completed = models.BooleanField(default=False)
this is what I get on the console when I use console.log(formdata):
csrfmiddlewaretoken=N91OUGSd6kBFkB1E2DMZuMW6qJD7cc3frPprwGMLTuupcg6PKYtt44jA4z5Lx6xX&todo=this%20is%20the%20content%20of%20my%20textbox
You don't need model_to_dict. So, try:
if form.is_valid():
form.instance.author_id = request.user.id
new_form = form.save()
return JsonResponse({'task': new_form}, status=200)
else:
return redirect('trylang:todo-list')
return redirect('trylang:todo-list')
EDIT
You are submitting the form not through ajax. When you click button it was submitting the form. So, e.preventDefault() should do the job.
$(document).ready(function(){
$("#createbutton").click(function(e){
e.preventDefault(); <--- You were missing this
var formdata = $("#addtodoform").serialize();
$.ajax({
url: $("#addtodoform").data('url'),
data: formdata,
type: 'post',
success: function(response){
$("#tasklist").append('<div class="card mb-1" ><div class="card-body">'+ response.task.todo +'<button type="button" class="close"><span aria-hidden="true">×</span></button></div></div>')
}
});
});
});