In my Django project, I have set up pyfacebook & django-facebookconnect to let the user login with their Fb account. However I now need to get the right permissions to get the user's data & save it in my db.
How do you add the permissions to pyfacebook & django-facebookconnect?
In facebook.init.py there is this function which I think is where I need to change the scope somehow.
Thanks for the help!
def get_login_url(self, next=None, popup=False, canvas=True,
required_permissions=None):
"""
Returns the URL that the user should be redirected to in order to login.
next -- the URL that Facebook should redirect to after login
required_permissions -- permission required by the application
"""
if self.oauth2:
args = {
'client_id': self.app_id,
'redirect_uri': next,
}
if required_permissions:
args['scope'] = required_permissions
if popup:
args['display'] = 'popup'
return self.get_graph_url('oauth/authorize', **args)
else:
args = {'api_key': self.api_key, 'v': '1.0'}
if next is not None:
args['next'] = next
if canvas is True:
args['canvas'] = 1
if popup is True:
args['popup'] = 1
if required_permissions:
args['req_perms'] = ",".join(required_permissions)
if self.auth_token is not None:
args['auth_token'] = self.auth_token
return self.get_url('login', **args)
Update:
When you click the connect button, it passes facebookConnect:
<script type="text/javascript">
FB_RequireFeatures(["XFBML"], function() {FB.Facebook.init("{{ facebook_api_key }}", "{% url facebook_xd_receiver %}")});
function facebookConnect(loginForm) {
FB.Connect.requireSession();
FB.Facebook.get_sessionState().waitUntilReady(function(){loginForm.submit();});
}
function pushToFacebookFeed(data){
if(data['success']){
var template_data = data['template_data'];
var template_bundle_id = data['template_bundle_id'];
feedTheFacebook(template_data,template_bundle_id,function(){});
} else {
alert(data['errors']);
}
}
function pushToFacebookFeedAndRedirect(data){
if(data['success']){
var template_data = data['template_data'];
var template_bundle_id = data['template_bundle_id'];
feedTheFacebook(template_data,template_bundle_id,function(){window.location.href=template_data['url'];});
} else {
alert(data['errors']);
}
}
function pushToFacebookFeedAndReload(data){
if(data['success']){
var template_data = data['template_data'];
var template_bundle_id = data['template_bundle_id'];
feedTheFacebook(template_data,template_bundle_id,function(){window.location.reload();});
} else {
alert(data['errors']);
}
}
function feedTheFacebook(template_data,template_bundle_id,callback) {
FB.Connect.showFeedDialog(
template_bundle_id,
template_data,
null, null, null,
FB.RequireConnect.promptConnect,
callback
);
}
</script>
xd_receiver calls:
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.debug.js" type="text/javascript">
</script
Ultimately, I switched over to the django socialregistration module & that worked great.
Related
I'm struggling with the datatables reordering. I want when user reorder to update table in the database. For this to happen i need:
to configure the datatable to send request to the server.
send the information about reordered datatable to flask endpoint.
Process data on the backend and update database table.
I have read the documentation but it is not clear to me.
My code:
$(document).ready(function () {
var dt = $('#data').DataTable({
rowReorder: true,
dom: 'Bfrtip'
});
});
My own solution:
JavaScript code:
dt.on('row-reorder.dt', function (e, details, edit) {
var slownik = {};
for (var i = 0, ien = details.length; i < ien; i++) {
let id_asortymentu = details[i].node.id;
let nowa_pozycja = details[i].newPosition+1;
console.log(id_asortymentu);
console.log(nowa_pozycja);
slownik[id_asortymentu] = nowa_pozycja;
}
req = $.ajax({
url: 'asortymenty/tabela_reorder',
dataType: "json",
type: 'POST',
data : JSON.stringify(slownik)
});
req.done(function(data){
if (data.result == 1){
console.log('Table reordered.');
}
});
});
Flask backend code:
#admin.route('asortymenty/tabela_reorder', methods = ['GET','POST'])
def table_reorder():
slownik=request.get_json('data')
for key, value in slownik.items():
asort = Asortyment.query.get(key)
print(asort.pozycja)
asort.pozycja = value
db.session.add(asort)
db.session.commit()
return jsonify({'result' : '1'})
I have a model that references other models, I am trying to save data using ajax
Example:
class Friend(models.Model):
name = ...
class Main(models.Model):
name = ....
friend = models.ForeignKey(Friend, on_delete=models.CASCADE)
All body comes from ajax(fetch) request
I have a table (html), and add data to cells, then with the
enter event, send data.
Like this:
input.addEventListener("keyup", function (e) {
//in this scenario I already have the whole row
// get full_row `row_data`
post_ajax = {
method: "POST",
headers: {
"X-CSRFToken": crf_token, // I get it with a regular expression
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
Accept: "application/json",
},
body: JSON.stringify(row_data),
};
fetch("my_url", post_ajax)
.then((res) => res.json())
.catch((error) => console.error("Error:", error))
.then((response) => console.log("Success:", response));
});
My view function
def save_post(request):
if request.is_ajax and request.method == "POST":
body_unicode = request.body.decode('utf-8')
data = json.loads(body_unicode)
print('here the data arrives',data)
# here the data arrives {'name': 'Ale', 'friend_id': 22}
Main.objects.create(name=data['name'], friends=data['friend_id'])
return JsonResponse({"instance": data}, status=200)
return JsonResponse({"error": ""}, status=400)
This is the error
raise TypeError("%s() got an unexpected keyword argument '%s'" %
(cls.__name__, kwarg))
TypeError: Main() got an unexpected keyword argument 'Friends'
Any idea or suggestion?
EDIT:
When you are creating the Main object, try making the "friend" attribute an object, like this:
friend = Friend.objects.get(id=data['friend_id'])
Main.objects.create(name=data['name'], friend=friend)
Also, the main issue appears to be you are calling the column "friends" but it should be "friend" when you are creating the Main object.
This:
Main.objects.create(name=data['name'], friends=data['friend_id'])
Should be:
Main.objects.create(name=data['name'], friend=data['friend_id'])
PREVIOUS ANSWER:
Assuming you are using JQuery in the template to send an AJAX request, since you did not specify.
In your urls.py:
...
path('/api/post_friend/', post_friend_api, name="post_friend_api"),
...
In your template :
<script type="text/javascript">
$("#myBurron").click(function(){
var csrfToken = $( "input[name='csrfmiddlewaretoken']"); // assuming this is a form
var friend_name = $("#friend_name").val();
$.ajax({ url: '{% url 'post_friend_api' %}',
type: "POST",
dataType: "json",
data: {'friend':friend_name, 'csrfmiddlewaretoken':csrfToken.val()},
cache: false
}).done(function(data) {
if (data.result === true){
alert(data.message);
}
});
});
});
</script>
In your views.py:
from django.http import JsonResponse
def post_friend_api(request):
data = {}
if request.POST.get('friend', None) is not None:
friend_name = request.POST.get('post_note')
# save the object and indicate success
data['result'] = True
data['message'] = "Friend saved successfully"
...
if request.is_ajax():
return JsonResponse(data)
else:
return HttpResponseBadRequest()
When you are sending data via POST don't forget to pass along your CSRF token as in the example above. This assumes you have a form on the page you can get it from, otherwise you can use something like this to get it:
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');
If you don't want to deal with the CSRF token, you can mark the view with the #csrf_exempt decorator and remove the 'csrfmiddlewaretoken' data element from the Ajax call in the template, but it may not be ideal or the most secure. An example of that:
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
#csrf_exempt()
def post_note_api(request):
...
If you post more details I can update my answer.
I'm confused about how to do it via Ajax or Json, but how can I send the selection array (curCheck) on-click to Django views and receive it as a python array
javascript
document.getElementById('results').addEventListener('click', function(){
html_table = '<thead><tr><th>Currency</th><th>Amount</th><th>Symbol</th>><tr/><thead/>'
var checkElements = document.getElementsByClassName('ch');
for(var i =0; i< curname.length; i++){
if (checkElements[i].checked) {
var curChecked = curname[i];
var JsonArr = JSON.stringify(curChecked);
postcurChecked(JsonArr)
html_table += '<tr><td>' + curname[i] + '</td>';
}
}
document.getElementById('result_table').innerHTML = html_table;
},false;
ajax
function postsubChecked(curChecked) {
$.ajax({
"url": "http://127.0.0.1:8000/results/",
"type": "POST",
"data": {"checkbox": curChecked},
"headers": { 'X-CSRFToken': getCookie('csrftoken')}
})
}
in django
def currencyChecked(request):
body_unicode = request.body.decode('utf-8')
body_unicode = body_unicode.replace('%22','')
print(body_unicode) json_data = json.loads(body_unicode.read())
I would like to see the python array print to see it is passed to the back
but I keep getting this error:
json_data = json.loads(body_unicode.read()) AttributeError: 'str' object has no attribute 'read'
For getting the selected checkbox values and sending as an array using ajax you can use jquery like this:
consider you have multiple checkboxes and a button.
<input type="checkbox" name="imageName">
<input type="checkbox" name="imageName">
.......
<button id="deletePhoto">Delete</button>
after selecting multiple checkbox values click on this button. On clicking the below jquery will be triggered to make an arrya of selected checkbox values.
//jquery for getting the selelcted checkbox values
$(document).on("click","#deletePhoto",function(){
var favorite = [];//define array
$.each($("input[name='imageName']:checked"), function(){
favorite.push($(this).val());
});
alert("Photo Selected: " + favorite.join(", "));
if(favorite.length == 0){
alert("Select Photo to delete");
return false;
}
//ajax for deleting the multiple selelcted photos
$.ajax({type: "GET",
url: "/olx/deletePhotoFromEdit",
data:{
favorite:favorite
},
success: function(){
// put more stuff here as per your requirement
});
}
});
});
In the view you can get the array like this:
selected_photo = request.GET.getlist('favorite[]')
I'm making a POST request from AngularJS to Python.
I started with an JavaScript example. It works properly returning all the values.
However, when I try to do it from AngularJS I'm not able to read the value of the variable posted.
JAVASCRIP EXAMPLE THAT WORKS PROPERLY (I'm able to get the value (Mike) back of Name):
JS code
<script language="Javascript">
function asyncChange()
{
var request;
if (window.XMLHttpRequest) {
request = new window.XMLHttpRequest();
} else {
// Versiones antiguas de Internet Explorer.
request = new window.ActiveXObject("Microsoft.XMLHTTP");
}
request.open("POST","nctest.py" , true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send("Name=Mike");
request.onreadystatechange = function()
{
if (request.readyState == 4 && request.status == 200)
{
document.getElementById("myLabel").innerHTML = "Hello " + request.responseText + "!";
}
}
}
</script>
nctest.py
#!/usr/bin/python
import cgi
input = cgi.FieldStorage()
print "Content-type: text/html\n\n"
print "input[Pe].value: "
print input["Pe"].value
ANGULARJS DOESN'T WORK PROPERLY (I'm not able to get the value (Mike) back of Name):
Angularjs code:
(function(){
'use strict'
var sectest= {
controller:sectestCtrl,
templateUrl:'app/components/component_test/test.html',
}
angular
.module('myapp')
.component('secTest',sectest);
function sectestCtrl($http){
var prac= this;
prac.method = 'POST';
prac.url = 'nctest.py';
prac.data = {Name : 'Mike'};
prac.data_answer
prac.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
prac.sendHTML = send;
function send(){
prac.code = null;
prac.response = null;
$http({method: prac.method, headers: prac.headers, url: prac.url, data: $.param(prac.data)}).
then(function(response) {
prac.status = response.status;
prac.data_answer = response.data;
console.log("OK prac.data_answer: ", prac.data_answer)
}, function(response) {
prac.data_answer = response.data || 'Request failed';
prac.status = response.status;
});
};
}
})();
nctest.py code
#!/usr/bin/python
import json
import cgi
input = cgi.FieldStorage()
print "Content-type: text/html\n\n"
print input["Name"].value
The problem is that prac.data_answer prints blank value.
I have already try with different headers for both angularjs and python codes but none seems to work:
prac.headers = { 'Content-Type': 'application/json' };
prac.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
prac.headers = { 'Content-Type': 'text/html\n\n' };
Many thanks.
There are 2 separate issues you're trying to address. Server (CGI) & client(angularjs). First check to see that you are receiving the data over the network - using Chrome developer tools, under the Network tab. If so, there's no need to change the Content-Type to json, since angular by default assumes all http data is in json format.
I don't think you need all those attributes for a post request. Seems like an overkiller when it can be simpler. Try this:
$http.post(url, data).then(function(response){
console.log(response.data);
});
I want to send POST request to view function. Now I am getting 500 error. I could not figure out where is the problem. The view function is receiving POST request but not returning any data.
EDIT: Now problem with 500 error solved. But how should I return form for editing object?
Template:
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]);
// 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 editParticipant(event_id, row_id){
var postdata = {
'csrfmiddlewaretoken': csrftoken
}
$.post( "/edit-participant-" + event_id + "/", postdata, function( data ) {
console.log(data);
});
}
View:
def edit_participant(request, participant_id):
participant = Participant.objects.get(pk=participant_id)
form = RegisterToEvent(request.POST or None, instance = participant)
if form.is_valid():
form.save()
return HttpResponseRedirect('/event-%s' %2)
data = {'form': form}
return JsonResponse(data)
URL:
url(r'^edit-participant-(?P<participant_id>[0-9]+)/$', 'event.views.edit_participant', name='edit_participant'),
Your view doesn't return a response
def edit_participant(request, participant_id):
return JsonResponse({'data':"Test"})
You should also turn on debug in the settings by setting DEBUG to true, it will tell you exactly what the error is, just remember to turn this off before production. You can also implement error logging.
There isn't anything about this function that needs to use ajax requests. If you want to keep the same page if the form isn't valid, then just return the form errors and do something with them
data = { 'errors': form.errors }
But this doesn't make much sense to me when you can just load the page again with a form and let django do it for you with its form rendering.
return render(request, 'yourhtml.html', {form: form})