Ajax is not saving data in DataBase - javascript

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)

Related

How to add data from javascript in databases django

I'm new with Django Framework. I made a template in html using a script javascript.
It looks like a chat. I want to put answers from user in my databases.
Here is the link with my code: https://codepen.io/maria-lupu-the-sasster/pen/abGdgPQ
And the end, after the "conversation" is over and appear the button "Let's go", I want all the details (that 'uid' and name) to be added in my databases.
There are my model where I want to add the details:
class Employee(models.Model):
employee_id = models.BigAutoField(primary_key=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
u_id=models.CharField(max_length=20)
badge_number=models.CharField(max_length=50)
email_adress = models.CharField(max_length=300)
role = models.CharField(max_length=40)
def __str__(self):
return self.last_name
for first_name and last_name I was thinking of doing a split to the string provided by the user (that time when the bot from chat ask user for his name)
email_adress will be composed with uid+#gmail.com
I searched on google for many solutions, but I still don't know how to do it. I saw something with Ajax, but I don't know how to work with this. Please, can someone help me and explain me?
So this is an example Ajax Post for django and a basic view (might be better to use forms)
If being logged in is required you need to place: {% csrf_token %} somewhere in the template and csrfmiddlewaretoken needs to be included with the post.. or maybe you always need it?- idk i've always included it.
function save(employee_id, first_name, last_name, u_id, badge_number, email_adress, role){
postData = {
'employee_id': employee_id,
'first_name': first_name,
'last_name': last_name,
'u_id': u_id,
'badge_number': badge_number,
'email_adress': email_adress,
'role': role,
// if login is required you need to pass this,
'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val(),
};
$.ajax({
method: 'post',
url: 'url_to_save_view', // put your URL here
data: postData,
success: function(data){
console.log(data);
// do things
},
error: function(event,xhr,settings,errorText){
alert('error');
}
});
}
def saveconvo(request):
if request.method == 'POST':
Employee.objects.create(
employee_id=request.POST.get('employee_id'),
first_name=request.POST.get('first_name'),
last_name=request.POST.get('last_name'),
u_id=request.POST.get('u_id'),
badge_number=request.POST.get('badge_number'),
email_adress=request.POST.get('email_adress'),
role=request.POST.get('role'),
)
return HttpResponse(
json.dumps({'status':True),
content_type="application/json"
)

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

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.

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')

Save to LocalStorage on a condition

I've script two script that i want to merge as one . Script 1 is for checking if email and password is right it brings out a success message "Correct" and it logs you in. Script 2 is what i use to store the email and password in a localstorge
Script 1
$(document).ready(function(){
$("#form1").on('submit',function(event){
event.preventDefault();
data = $(this).serialize();
$.ajax({
type: "POST",
url: "log.asp",
data: data,
success: function(data) {
$('#log_msg').html(data);
var result = $.trim(data);
if(result==="Correct"){
window.location = 'source.asp';
}
}
});
});
});
Script 2
$(function() {
var
$email = $('#email'),
$password = $('#password'),
localEmail = localStorage.getItem("eaddress"),
localPwd = localStorage.getItem("pwd");
// SAVE VARIABLES TO LOCAL STORAGE
$('#form1').on('submit', function() {
localStorage.setItem("eaddress", $email.val());
localStorage.setItem("pwd", $password.val());
});
});
Now i want to merge the two together that it should only save the email and password in the localstorge if the success message is equal
to "Correct" and also logs you in
Never ever store passwords on the client!
Never store passwords unencrypted!
To store the email address in the localStorage you can use this snippet:
$(document).ready(function(){
$("#form1").on('submit',function(event){
event.preventDefault();
var data = $(this).serialize();
$.ajax({
type: "POST",
url: "log.asp",
data: data,
success: function(data) {
$('#log_msg').html(data);
var result = $.trim(data);
if(result==="Correct"){
localStorage.setItem('eaddress', $('#email').val());
}
}
});
});
});
Note: You have to cleanup the localStorage yourself. If you want to store the data for further identification use a sessionId in a cookie or use the sessionStorage for saving temporary data.
Edit: To submit the form after page load you can try something like this:
$(function(){
var eAddr = localStorage.getItem('eaddress');
if (eAddr !== null) {
$('#email').val(eAddr);
$('#form1').trigger('submit');
}
});
Note: If you store the password encrypted on the client and submit it trough the form, the authentication process is quiet insecure.
I think your authentication design is wrong. You should use an authentication cookie (like a session cookie) and validate it on the server side. Without submitting a form every time a page loads nor storing credentials on the client side.

Categories