How to call Django API with Javascript with Authenticated user in Django - javascript

I'm using Django for Backend, PostgresSQL as DB and HTML, CSS and Javascript as Frontend. I am calling Django API via Javascript. Where user is adding a product to a cart, and I'm calling the cart with DRF to show all the data to the user. But problem is that, user can see all the data of other user. So, how can authenticated user can see his/her selected product on a cart.
Here is a detailed code:
views.py
adding product to cart
def addProduct(request):
user = request.user
product_id = request.GET.get('product_id')
product_cart = Product.objects.get(id=product_id)
Cart(user=user, product=product_cart).save()
return render(request, 'cart/addtocart.html')
Api View (views.py)
#api_view(['GET'])
def showproduct(request):
if request.method == 'GET':
result = Cart.objects.all()
serialize = productserializers(result, many = True)
return Response(serialize.data)
serializer.py
from .models import *
from rest_framework import serializers
class productserializers(serializers.ModelSerializer):
class Meta:
model = Cart
fields = '__all__'
depth = 1
Javascript to call Django API
$(document).ready(function() {
$.ajax({
url: 'http://127.0.0.1:8000/showproduct/',
dataType: 'JSON',
success: function(data){
for (var i = 0; i < data.length; i++)
{
var row =
$('<tr> .. ..........</tr>');
$("#table").append(row);
}
}
});
});
NOW, How to show the specific user(authenticated user) there specific cart item.

you have to pass user id when you are calling ajax.
If you are using GETmethod than pass user id in URL and access it via argument in your view for eg.
$(document).ready(function() {
$.ajax({
url: '{% url "showdata" %}',
dataType: 'JSON',
success: function(data){
for (var i = 0; i < data.length; i++)
{
var row =
$('<tr> .. ..........</tr>');
$("#table").append(row);
}
}
});
});
and in your views.py
#api_view(['GET'])
def showproduct(request):
if request.method == 'GET':
result = Cart.objects.filter(user=request.user)
serialize = productserializers(result, many = True)
return Response(serialize.data)
and add this in your urls.py
urlpatterns = [
path("showdata/", views.showproduct, name='showdata')
]
UPDATE
there is no need to pass user id in ajax URL if user is authenticated than user will come in request
so please change you views.py, urls.py and ajax URL.

Related

How to update a value in database after n seconds of query made? Django

I have a model in which I created a field "bargain price " as shown in Models.py:
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
bargainprice = models.FloatField(default=0)
somewhere in my template I take input from user and update the bargain price using ajax as shown below:
$.ajax({
url: "/bargain/" + id + "/",
data: { csrfmiddlewaretoken: window.CSRF_TOKEN, 'input': parseFloat(input) },
type: 'POST'
}).done(function (response) {
alert(response);
});
and I successfully update the price by the view:
def Bargain(request, uid):
if request.method == 'POST':
item = Item.objects.get(id=uid)
item.bargainprice = request.POST['input']
item.save()
message = 'update successful'
return HttpResponse(message)
else:
return HttpResponse("this is not working..")
**Now what I want. I want to reset this Bargain_price updated value to default after n seconds **
Can anyone suggest to me the method to do it? Thanks in advance.

Ajax is not saving data in DataBase

I am building a BlogApp and I am stuck on a Problem.
What i am trying to do
I am trying to access user's location via JavaScriptand saving in the Model's instance in DataBase.
Accessing location is working fine. BUT saving is not working
The Problem
Location's city is not saving in DataBase. When i refresh the page then it doesn't save in DataBase.
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,default='',unique=True)
full_name = models.CharField(max_length=100,default='')
city = models.CharField(max_length=30,default='')
views.py
def func(request):
city = request.GET.get('city')
city.save()
message = 'Updated'
return HttpResponse(message)
template (.html)
# Getting city name ( first javascript code ) through IP is working.
<script>
$.ajax({
url: "https://geolocation-db.com/jsonp",
jsonpCallback: "callback",
dataType: "jsonp",
success: function(location) {
$('#city').html(location.city);
}
});
</script>
#This code is for send data to Django.
<script>
$("city").change(function)(){
const city = 'city';
$.ajax({
url ="{% url 'mains:func' %}",
data = {
'city':city,
} ,
success.function(data){
console.log("Update");
}
});
};
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div>City: <span id="city"></span></div>
I don't know where is the Problem.
Any help would be Appreciated.
Thank You in Advance.
You need to update the profile instance belonging to the user which is referenced on the request. (This is assuming the request is for a logged in user).
def func(request):
city = request.GET.get('city')
user = request.user
profile = Profile.objects.get(user=user)
profile.city = city
profile.save()
message = 'Updated'
return HttpResponse(message)

How to display the name that matches the ID without refreshing/submitting the form in Django?

I am trying to display a User's name on top of a box where they enter their Employee # in a form, without having to refresh the page.
For example, they enter their # and then after they click/tab onto the next field, it renders their name on top, which comes from the database, so the user knows they've entered the correct info. This name is stored in a separate model, so I try to retrieve it using the "id/number".
I am not too familiar with AJAX but after reading a few similar questions it seems like an AJAX request would be the most appropriate way to achieve this. I tried to make a function get_employee_name that returns the name of the person based on the way I saw another ajax request worked, but I'm not sure how to implement this so it displays after the # is entered.
My page currently loads, but there is never a call to the function/url that searches for the name to display it on the page (because there isn't one). I'm not sure where I might be missing the part that connects these two areas of the code or how to connect these, as I am not too familiar with html and Django, most of this has been trial and error.
models.py
class EmployeeWorkAreaLog(TimeStampedModel, SoftDeleteModel, models.Model):
employee_number = models.ForeignKey(Salesman, on_delete=models.SET_NULL, help_text="Employee #", null=True, blank=False)
work_area = models.ForeignKey(WorkArea, on_delete=models.SET_NULL, null=True, blank=False)
station_number = models.ForeignKey(StationNumber, on_delete=models.SET_NULL, null=True, blank=True)
This is the model where the name is stored
alldata/models.py
class Salesman(models.Model):
slsmn_name = models.CharField(max_length=25)
id = models.IntegerField(db_column='number', primary_key=True)
I was reading I can add to the "attrs" in the widget an 'onchange' part, but I am not too familiar with how to approach this and tying it to the ajax request from forms and not the html.
forms.py
class WarehouseForm(AppsModelForm):
class Meta:
model = EmployeeWorkAreaLog
widgets = {
'employee_number': ForeignKeyRawIdWidget(EmployeeWorkAreaLog._meta.get_field('employee_number').remote_field, site, attrs={'id':'employee_number_field'}),
}
fields = ('employee_number', 'work_area', 'station_number')
views.py
def enter_exit_area(request):
form = WarehouseForm(request.POST or None)
if form.is_valid():
# Submission stuff/rules
return render(request, "operations/enter_exit_area.html", {
'form': form,
})
def get_employee_name(request):
employee_number = request.GET.get('employee_number')
try:
employee = Salesman.objects.get(id=employee_number)
except Salesman.DoesNotExist:
return JsonResponse({'error': 'Employee not found'}, status=404)
employee_name = employee.slsmn_name
return JsonResponse({'employee_name': employee_name})
urls.py
urlpatterns = [
url(r'enter-exit-area/$', EnterExitArea.as_view(), name='enter_exit_area'),
path('get-employee-name/', views.get_employee_name, name='get_employee_name'),
]
The ajax request I tried to create is at the end of this html. I modified a similar request I found, but it does not actually display anything on the screen, not sure if I'm missing an area where the request is actually never being called, as I am not too familiar with how these types of requests work.
enter_exit_area.html
{% extends "base.html" %}
{% block main %}
<form id="warehouseForm" action="" method="POST" novalidate >
{% csrf_token %}
<div>
<div>
<!-- Here is where I would want the name to render after the user enters their number and tabs out -->
{{ form.employee_number.help_text }}
{{ form.employee_number }}
</div>
<div>
{{ form.work_area.help_text }}
{{ form.work_area }}
</div>
</div>
<div>
<div>
<button type="submit" name="enter_area" value="Enter">Enter Area</button>
</div>
</div>
</form>
<script>
$("#id_employee_number").change(function () {
var employee_number = $(this).val();
var url = $("#warehouseForm").data("employee-name");
$.ajax({
url: url,
type:'GET',
data: {
'id': employee_number
},
success: function (data) {
var employee_name = data['employee_name'];
$('#employee_name').text(employee_name);
},
error : function (data) {
var error_message = data['error'];
$('#employee_name').text(error_message);
}
});
});
</script>
{% endblock main %}
How can I call the function from the HTML? Could I do it in such a way that when the user enters 6 numbers it checks? (All employee numbers are 6 digits)
The url has to be the endpoint url which you defined in your url.py file
<script>
$("#id_employee_number").change(function (e) {
e.preventDefault();
var employee_number = $(this).val();
var url = $("#warehouseForm").data("employee-name");
$.ajax({
url: "/get_employee_name", // Here
type:'GET',
data: {
'id': employee_number
},
success: function (data) {
var employee_name = data['employee_name'];
$('#employee_name').text(employee_name);
},
error : function (data) {
var error_message = data['error'];
$('#employee_name').text(error_message);
}
});
});
</script>
You can append to your GET request a url parameter like: /get-employee-name/<your employee number here>
I recommend taking a look at URL Dispatcher to create url parameters within your django url definitions
I also recommend using underscores NOT dashes in your url definitions.
So a pseudo working config would be
urls.py
urlpatterns = [
url(r'enter-exit-area/$', EnterExitArea.as_view(), name='enter_exit_area'),
path('get_employee_name/<int:employeeNum>', views.get_employee_name, name='get_employee_name'),
]
views.py
def get_employee_name(request, employeeNum): #You get the employeeNum variable from urls.py
try:
employee = Salesman.objects.get(id=employee_number)
except Salesman.DoesNotExist:
return JsonResponse({'error': 'Employee not found'}, status=404)
employee_name = employee.slsmn_name
return JsonResponse({'employee_name': employee_name})
script
<script>
$("#id_employee_number").change(function () {
var employee_number = $(this).val();
var employeeNum = $("#warehouseForm").data("employee-name");
$.ajax({
url: `/get_employee_name/${employeeNum}`,
type:'GET',
success: function (data) {
var employee_name = data['employee_name'];
$('#employee_name').text(employee_name);
},
error : function (data) {
var error_message = data['error'];
$('#employee_name').text(error_message);
}
});
});
</script>

AJAX not updating database query as intended

I have pages that use both django context variables and json data. The first page is the "master page" that just displays all available data. The other pages however, are loaded upon submission of a dropdown form where the user can select a specific account to view. When the user selects an account and submits the dropdown form, two things are designed to happen:
The form action goes to a django view function that makes several queries to the database, then passes context variables upon rendering the template. Next however Chart data is supposed to be loaded via Ajax from a certain url that returns a JSONResponse with the data. The chart data seems to load fine for the "master" page, since all data is shown when I visit the url where the data is sent. Upon selecting a specific account however, I want to pass a request to a url to filter the database based on the selection, thereby producing specific chart data. This is the part that doesn't seem to work, as when I select a specific account, I cant seem to get the chart data for only that specific account to show. Here is my code:
urls.py
from django.conf.urls import url, include
from . import views
from .views import get_master_data, get_specific_data
views.py
### SELECTED METER DATABASE DATA PULL ###
def get_specific_data(request, *args, **kwargs): ### This isn't working as intended ###
if request.method == 'POST':
selected_meter = request.POST.get('selected_meter')
usage_data = list(MeterData.objects.filter(name=selected_meter).order_by('date').values_list('usage', flat=True))
#### A bunch of other similar queries ####
data = {
"usage_data": usage_data,
#### corresponding parts for other queries not shown ####
}
return JsonResponse(data)
else:
usage_data = list(MeterData.objects.order_by('date').values_list('usage', flat=True))
##### A bunch of other similar queries #####
data = {
"usage_data": usage_data,
#### corresponding parts for other queries not shown ####
}
return JsonResponse(data)
template.html
// This script is what gets the chart data. This works on the master page //
<script>
var categories = [];
var data = [];
var endpoint = '/properties/api/chart/data/'
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
categories = data.dates
usageData = data.usage_data
OldCostsData = data.oldCosts_data
NewCostsData = data.newCosts_data
OldRatesData = data.oldRates_data
NewRatesData = data.newRates_data
savingsData = data.savings_data
Chart.defaults.global.defaultFontFamily = "Gotham-Black";
var usageCanvas = document.getElementById("usageChart");
var ratesCanvas = document.getElementById("ratesChart");
var costsCanvas = document.getElementById("costsChart");
var savingsCanvas = document.getElementById("savingsChart");
}
});
</script>
// This is supposed to post the dropdown menu selection on submission before loading the new template thus querying specific chart data //
<script>
var meterForm = $('#property-select');
var specificDataUrl = '/properties/api/specific-chart/data/';
meterForm.submit(function(event){
event.preventDefault();
$.ajax({
type: "POST",
url: specificDataUrl,
data: { selected_meter: $('#property-select option:selected').val() }, // data to be sent with the post request
success: function(data) {
console.log(data)
},
});
});;
</script>
<!-- This is the form -->
<form method="POST" action="/properties/property-selected/" id="property-select">
{% csrf_token %}
<select name="meters" class="dropdown-content">
{% for meter in user_meters %}
<option value="{{ meter }}">{{ meter.name }}</option>
{% endfor %}
</select>
<input type="submit" value="Submit" class="submit-button" style="margin-top:30px;"/>
</form>
I'm not really sure why the specific data query for charts data isn't working. Any help would be much appreciated, thanks!
In your Javascript you're posting the request with a parameter called selected_meter:
data: { selected_meter: $('#meter-option').val() }
But your view is asking for a post parameter called selection:
selected_meter = request.POST.get('selection')
Update your view or the Javascript to make the parameter names the same, e.g.
selected_meter = request.POST.get('selected_meter')

Ajax POST not sending data when calling 'request.POST' in Django view

I am attempting to get an Ajax POST to to send data to my view so I can manipulate my data there, when I click on a div with class up-arrow.
Problem is, when I click said div and print request.POST in my view file, I am getting a POST object that contains <QueryDict: {}>. Empty! I can't seem to figure out why my the POST request isn't sending my data through.
Here is my HTML...
{% for i in post.posts %}
<li>
<div>
<div class='up-arrow'>
</div>
{{i}}
</div>
</li>
{% endfor %}
Here is my AJAX/jQuery...
$(document).ready(function(){
$('.up-arrow').click(function(){
$(this).hide()
console.log('click')
$.ajax({
headers: {
'Content-Type':'application/json',
'X-CSRFToken': getCookie('csrftoken')
},
url: 'voteuppost',
type: 'POST',
data: {'dane': 123456789101112},
success: function(data) {
alert('success!')
},
error: function(){
alert('fail')
}
})
return false
});
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
})
Here is my view...
class VoteUpPost(View):
def post(self, request):
print(request.POST)
return JsonResponse({'status': True})
Here is my url route...
url(r'^voteuppost$', VoteUpPost.as_view()),
Things I have tried...
1) I used GET instead of POST and I am able to get the data value using request.GET.get('dane')
1) Tried using request.POST.data and request.POST.DATA and get the following... AttributeError: 'QueryDict' object has no attribute 'data'
and I also get a 'fail' alert.
How do I send my data over to my view via a POST request and then access the data within?
When posting JSON data with application/json you need to use request.body instead of request.POST.
Like so:
class VoteUpPost(View):
def post(self, request):
print(request.body)
data = json.loads(request.body)
return JsonResponse({'status': True})
Also as Jacques mentioned, make sure to update your js to pass a JSON string.
Change:
data: {'dane': 123456789101112},
To:
data: JSON.stringify({'dane': 123456789101112}),
Django request can only parse application/x-www-form-urlencoded and
multipart/form-data to request.POST. For other content types you have to use request.body property. for assertion of content type you can get the content type from request.META.get('CONTENT_TYPE')
def sample_view(request):
if request.META.get('CONTENT-TYPE') == 'application/json':
data = json.loads(request.body)
return JsonResponse({'any-message':'Hello'})

Categories