Concurrent request to Django API from vue returns the response from the last request for both.
Here is my snippet from vue component
methods:{
users(){
axios.get('users').then((response) => {
this.sers = response.data;
}).catch((error) => {
console.log(error);
});
},
new_users(){
axios.get('users', {
params: {type:'new'},
}).then((response) => {
this.new_users = response.data;
}).catch((error) => {
console.log(error);
});
}
},
mounted(){
this.users();
this.new_users();
}
and my python snippet from the Django view
def list_objects(request):
if 'type' in request.GET and request.GET['type'] =='new' :
#return new users
else:
#return users
The problem is the new_users() and users() methods respond with new users data(the one which called last, if we call the users() method last both methods get users data )
The problem is with the Django development server. When I switch to gunicorn all problems gone and now working as expected.
Related
I'm using python to create wordpress post taking care also of the YOAST fields, using the wordpress rest api. On YOAST website I found this statement:
The Yoast REST API is currently read-only, and doesn't currently
support POST or PUT calls to update the data.
At the same time, I'm wondering if there is some workaround to be able to update the Yoast fields by post request, something like this (that off-course is not working right know):
post = {
'title' : 'My title',
'content' : 'This is my first post created using rest API Updated',
'yoast_head_json': {'title': 'This field should be UPDATED by POST REQUEST'},
}
I found a code snippet at this link, that maybe would be a useful starting point and I report it below:
class YoastUpdateController extends WP_REST_Controller {
public function register_routes() {
register_rest_route( 'wp/v2/', '/action/', array(
'methods' => 'GET',
'callback' => [$this, 'update_yoast_meta']
));
}
function update_yoast_meta($data) {
$postID = $_GET['postID'];
$metadesc = $_GET['metaDesc'];
if ($postID && $metadesc) {
$this->add_to_yoast_seo($postID, $metadesc);
}
}
function add_to_yoast_seo($post_id, $metadesc){
$ret = false;
$updated_desc = update_post_meta($post_id, '_yoast_wpseo_metadesc', $metadesc);
if($updated_desc){
$ret = true;
}
return $ret;
}
}
function register_yoast_update_controller() {
$controller = new YoastUpdateController();
$controller->register_routes();
}
add_action( 'rest_api_init', 'register_yoast_update_controller' );
I placed the above code in function.php, I hope it is the right place.
How could I update all/some of the fields of YOAST by rest api post request? Below some fields (E.g. title, description...)
"yoast_head_json": {
"title": "Post 1 - MyWebsite",
"description": "Meta description added in backend",
"robots": {
"index": "index",
"follow": "follow",
"max-snippet": "max-snippet:-1",
"max-image-preview": "max-image-preview:large",
"max-video-preview": "max-video-preview:-1"
},
Thank you all,
According to yoast documentation: The Yoast REST API is currently read-only, and doesn't currently support POST or PUT calls to update the data.
https://developer.yoast.com/customization/apis/rest-api/#can-i-use-this-api-to-update-data
I have a Django 3 application with jQuery Ajax posts on bootstrap modals.
There are few buttons that do not have any form but uses post to call certain urls.
All the Django methods are implemented as stated here: https://docs.djangoproject.com/en/3.0/ref/csrf/ All the headers are sent properly.
The page and and functionality works fine when user has logged in and also after user has logged out.
However the Ajax calls return the error response as Forbidden (CSRF cookie not set.), when visiting the site first time and in Incognito mode when not logged in. Once user logs in the issue gets resolved, even after the user logs out.
Please guide as to what may be the probable reason.
Edit: As requested in comments, PFB one of the many Ajax calls.
<script>
$('.likelink').on("click", function (event){
event.preventDefault();
var postid = $(this).attr("data-catid");
$.ajax({
type: 'POST',
url: "{% url 'like_post' %}",
data: {"post_id": postid},
success: function (response){
if(response["valid"]){
alert("Yeah!!! You Liked the post :)");
$('#likelinkid'+postid).remove();
}
else{
alert("Kindly login to Like!!!");
}
},
error: function (response){
alert(response["responseJSON"]["error"]);
}
});
});
</script>
Similarly there are multiple scripts lined to various anchor tags. The above script works fine when user is logged in and after the user logs out, as mentioned in the question.
Edit 2: Just for reference, I am writing the csrf related codes used as per Django documentation:
<script type="text/javascript">
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 = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
</script>
Apart from the above, I have also tried using the view decorators #requires_csrf_token and #ensure_csrf_cookie but that didn't solve the above issue.
This issue is resolved by moving the jQuery CDN reference from the child template to the base template and replacing the slim jQuery reference of BootStrap.
The earlier slim jQuery reference by Bootstrap in base template was causing an overlap issue with the minified jQuery referenced in the child template. I had used it as such in a hope to have better performance of webpages where full jQuery would not be needed, but it didn't help.
So when using Bootstrap, make sure you have only one jQuery referenced in extending templates and preferably before other Bootstrap references.
I'm showing data in table using django view, in addition I've bootstrap datatable that is responsible for pagination, searching and sorting functionalities. The problem is when I'm adding the data to the database (using ajax call) the pagination is not working and number of records is not refreshed.
view.py
def patients_list(request):
patients = Patient.objects.all()
return render(request, 'patients/patients.html', {'patients': patients})
ajax call for inserting data
var loadForm = function () {
var btn = $(this);
$.ajax({
url: btn.attr("data-url"),
type: 'get',
dataType: 'json',
beforeSend: function () {
$("#modal-book .modal-content").html("");
$("#modal-book").modal("show");
},
success: function (data) {
$("#modal-book .modal-content").html(data.html_form);
}
});
};
datatable
$(document).ready(function() {
$('#book-table').DataTable({
retrieve: true,
"order": [],
"columnDefs": [ {
"targets" : 'no-sort',
"orderable": false,
}]
});
});
Does anyone knows how can I refresh the datatable so that number of rows will align with newly added ones?
What I've tried already was ajax.reload() and ajax.draw(), but nothing worked.
I'm trying to use Ajax in order to validate if a value of a field already exists in the DB.
urls.py:
#App Auxiliares_Tipos:
path('ajax/validar_tipaux/', validar_tipaux),
path('Tipos_de_auxiliares/', tipoAuxi),
views.py:
def validar_tipaux(request):
codigo = request.GET.get('codigo', None)
print(codigo)
data = {
'is_taken': TipoAux.objects.filter(codigo__iexact=codigo).exists()
}
return JsonResponse(data)
validation.js is included in my html body.
validation.js:
$("#id_codigo").change(function () {
var tipaux = $(this).val();
console.log(tipaux);
$.ajax({
url: '/ajax/validar_tipaux/',
data: {
'tipaux': tipaux
},
dataType: 'json',
success: function (data) {
if (data.is_taken) {
console.log('Existe');
alert("That value is already taken.");
}
}
});
});
id_codigo is the id of the field that I'm checking if exists with Ajax.
The error: it works almost at all, the JavaScript detects changes on id_codigo properly (I'm trying to check everything with print/console.log). But it gets stuck in the view validar_tipaux where it prints None as codigo's value.
What's wrong?
You're sending the data as tipaux but your view is looking for codigo.
I am using angular2 as a front end in my html pages.I have a django project that uses postgresql.
Which is the best approach to use the angular2 in the django project to connect to the django models and the database to perform basic operations(CRUD)like Read,Update etc?
Currently I need to fetch the data from the database dynamically.
(e.g.If user clicks on the product from the product list then product details should be retrieved from the database and it is shown to the user)
Any advice or reference example link will be helpful.
Create REST api end points using Django (use DRF for standard REST api's or just use vanilla django to generate json response for the requests and call it REST api).
For ex:
/product/:id is the api end point you've created to fetch the details of a particular product in Django
Then use Angular to request throught those API's and get the responses and do whatever you want with that data.
For ex:
make a get request to /product/1 to fetch the details of a product with PK = 1 when the user clicks that product.
Browse through Github for some inspiration.
Checkout django-rest-framework
DRF is a django app that makes building ReST apps a breeze.
Checkout their quick tutorial to get a sense of how to use DRF in your project.
I'm recently working on the similar project you have. My approach is just like #praba230890 mentioned above.
Here are some samples...
Django
In views.py
class HView(APIView):
def get(self, request, format=None):
request_hero_id = request.query_params.get('id', None)
if request_hero_id:
return Response(
{
'id': 1,
'name': 'test',
'position': 'mid'
},
status=status.HTTP_200_OK
)
return Response(
{ 'error': 'does not exist' },
status=status.HTTP_404_NOT_FOUND
)
class HsView(APIView):
def get(self, request, format=None):
return Response(
[
{
'id': 1,
'name': 'test',
'position': 'mid'
},
{
'id': 2,
'name': 'test',
'position': 'mid'
}
],
status=status.HTTP_200_OK
)
In urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('shweb.urls')),
]
You will need to install django-cros-headers if you run into CROS errors. Also, you will need to configure your settings.py
Angular2
In api-service.service.ts
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/toPromise';
import { Hero } from '../utils/hero';
#Injectable()
export class ApiService {
/** Modify this later */
private backend_api_url: string = 'http://localhost:8000/api/';
private api_headers: Headers = new Headers(
{ 'Content-Type': 'application/json' }
);
constructor(private http: Http) { }
getHero(id: number): Promise<Hero>{
const url = `${this.backend_api_url}htest/?id=${id}`;
return this.http.get(url).toPromise().then(
response => response.json() as Hero
).catch(this.handleError);
} // END getHero
getHeroes(): Promise<Hero[]>{
const url = `${this.backend_api_url}htests`;
console.log(url);
return this.http.get(url).toPromise().then(
response => {
console.log(response.json());
return response.json() as Hero[];
}
).catch(this.handleError);
} // END getHeroes
private handleError(error: any): Promise<any>{
console.error('An error occurred', error); // TODO: update this
return Promise.reject(error.message || error);
}
}
In hero.ts
export class Hero{
id: number;
name: string;
position: string;
}
In your component file, inject the api-service into component
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit{
title: string = 'Dashboard';
heroes: Hero[] = [];
constructor(private apiService: ApiService){}
ngOnInit(): void{
this.getHeroes();
}
getHeroes(): void{
this.apiService.getHeroes().then(heroes => this.heroes = heroes);
} // END getHeroes
}
Basically, using API to retrieve data and cast into class; then, you can use those data.
PS. I haven't touched the credentials and security part. I believe you need to have some sort of Authentication implemented for secure API communication. (In my case, only GETs are allowed. Therefore, I put the security part for later.)
Hope this would help!