I have a django app where users can save their contacts. I am not building a flow to allow users to download their contacts locally.
To do so, I built a CTA ("download") that if clicked
Gets the id of the contact selected
Triggers an Ajax request to my views
In the view I get the contact id, retrieve the data from my DB and create a VCF card out of it. (A contact card - basically a text file)
Now I would like to have such file downloaded on the client's machine but I don't know how to do it.
I managed to do it if I redirect to a new url where the view does exactly what my view below does, I want to allow users to download the file without being redirected to a new page. Also, trying to avoid storing the contact ids in the URL.
That's why I am trying to use ajax but I think that's creating problems because and Ajax request waits JsonReponse from the view.
I tried both a GET or POST but it's not working.
This is my view currently:
def get(self, request, *args, **kwargs):
#Get the ids
ids = request.GET.getlist('contact_ids[]')
# Get contqacts associated with ids
contacts = Contact.objects.filter(id__in=ids)
# Transform contacts into long text
text = Vcard().GroupVcards(contacts)
#Create file on the fly and attach it to the response (is this correct actually?)
response = HttpResponse(content_type='text/plain')
response['Content-Disposition'] = 'attachment;filename=ven.vcf'
response.writelines(text)
#return
return response
This is the Jquery triggering the ajax
$('.Vcard').on('click', function(e) {
let id = $(this).data('contact_id')
$.ajax({
type: "GET",
url: Urls['action:DownloadContact'](),
data: {
csrfmiddlewaretoken: csrftoken,
'contact_ids': [id],
},
error: function(response){
console.log(response)
console.log('error')
},
success: function(response) {
console.log(response)
console.log('success')
}
});
})
Related
I develop a django application where I have a d3js interactive tree. I use d3.json to get the tree data from the django view. I have create a decorator to check if user is logged to allowed the request or not. I have no problem when the user is logged but when the decorator return the jsonResponse with redirection url I have only the status error with the status description.
I read d3js and promise documentation but I'm not found a answer to return a jsonresponse with my custom response.
d3.json(d.data.url).then(function(data) {
// process data no problem
}, function(error){
console.log(error);
});
def check_user_permission_js(view_function):
#wraps(view_function)
def wrapper(request, *args, **kwargs):
if request.user.is_authenticated:
return view_function(request, *args, **kwargs)
messages.warning(request,
"Your account doesn't have access to this page "
+ "or your session has expired. "
+ "To proceed, please login with an account that has access.")
return JsonResponse({'not_authenticated': True,
'redirect_url': settings.LOGIN_URL,'data':[]}, status=500)
return wrapper
I think this question is not specific to d3 or frontend code.
If you are using d3 v5, d3.json is a thin wrapper around the browser fetch API documented here, which seems to be correctly returning a non 200 status code. If the problem is that you're not getting the custom fields provided in JsonResponse to appear in the response returned to the frontend, then the issue is related to usage of the Django JsonResponse method, it isn't something that using a different data fetching library would change.
I No I don't think the error comes from django because I already use JSONresponse with ajax requests that work very well. Exemple:
$.ajax({
url: "/browser/project/get-header",
type: "POST",
success: function(data) {
// process my data
},
error: function(jqXHR){
if (jqXHR.responseJSON.message){
writeMessages(jqXHR.responseJSON.message, 'error');
}
else{
writeMessages(
'An error occur: the sample list can not be loaded!',
'error');
}
}
});
My problem is related to fetch and how d3js returns the error with d3.json.
To temporarily solve my problem I use requests like the one above but in the end I would like to use only the functions of D3JS.
I have a Django powered web-app which also utilizes the Django REST framework. I want to read and write to my database using the API generated by Django REST.
I can do this successfully when I hardcode the password of the current user, but I can't do this when I attempt to pass in the retrieved password from Django, as Django does not store the password as plain text. (I know I can change this, but I am hoping there is a better way).
Essentially, my logic flow is this:
user logs in using Django login form
user would like to write new data to database, but will need API token
Obtain API token (already generated when they sign up)
use this token to authenticate and POST JSON data to REST framework
I can do all of these steps above when I hardcode the password as plain text in my script, but I would like to "retrieve" the password and pass it automatically if possible.
Code below works as described above:
views.py
class DefaultsListView(LoginRequiredMixin,ListView):
model = models.DefaultDMLSProcessParams
template_name = 'defaults_list.html'
login_url = 'login'
def get_queryset(self):
return models.DefaultDMLSProcessParams.objects.filter
(customerTag=self.request.user.customerTag)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
testing = super().get_context_data(**kwargs)
userName = str(self.request.user.username)
passWord = str(self.request.user.password)
url = 'http://127.0.0.1:8000/api-token-auth/'
context = {'tokenURL': url, 'user':userName, 'pass':passWord}
return context
template.html
<div class = "debugging">
<p id = "csrf">{% csrf_token %}</p>
<p id = "tokenURL">{{tokenURL}}</p>
<p id = "user">{{user}}</p>
<p id = "pass">{{pass}}</p>
</div>
script.js
var csrfToken = document.querySelector("#csrf input").value;
var user = document.getElementById("user").innerHTML;
var pass = document.getElementById("pass").innerHTML;
var xhr = new XMLHttpRequest();
var url = "http://127.0.0.1:8000/api-token-auth/";
xhr.open("POST", url,);
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader( "X-CSRFToken", csrfToken);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.token);
}
};
var data = JSON.stringify({"username": user, "password": 'myhardcodedpass' });
xhr.send(data);
This script will log the API token of the current user to the console as expected. But instead of hardcoding the password, I would like to just pass it as a variable, but the password is a very long string as it is not stored as plain text (var pass). So trying to use pass is rejected, as it obviously isn't the correct password when passed as text.
Is there a way to decrypt this password, or translate it somehow? Or perhaps an easier way to retrieve the API token from Django REST?
First and foremost, you should definitely NOT store the password as plain text. That is never the solution in any case, and only will cause problems.
I have a few suggestions that you can potentially use, but the easiest would be to simply use a JSON Web Token which can easily be integrated with Django Rest Framework using the django-rest-framework-jwt library.
Your workflow would basically be as follows:
User logs in successfully, which returns a JWT to authenticate the user
The script would be included in the header of the request, and the middleware would be able to successfully identify and authenticate the user.
Hopefully this gives you an idea on how to move forward. Best of luck
I have a complex problem in sending and receiving data in react to django with axios.
I'm not using REST API. This is my Handel function which is related with my signup form tag and after each click on submit button this function executes:
HandelSignUp(e){
e.preventDefault();
let Username = this.refs.username.value;
let Pass = this.refs.pass.value;
let Email =this.refs.email.value;
axios({
url:'http://127.0.0.1:8000/signupAuth/',
mothod:'post',
data:{
username:this.Username,
pass:this.Pass,
email:this.Email
},
headers: {
"X-CSRFToken": window.CSRF_TOKEN,
"content-type": "application/json"
}
}).then(respons =>{
console.log(respons);
})
.catch(err =>{
console.log(err);
});
and also this is my django urls.py :
urlpatterns = [
path('signupAuth/',ReactApp_View.signupRes),
]
ReactApp_View is my views.py in ReactApp file which I imported correctly.
ok now let's see my views.py:
def signupRes(request):
body_unicode = request.body.decode('utf-8')
data = json.loads(myjson)
return HttpResponse(request.body)
after all when I fill my signup fields and then click on button I see this massage in console log of my browser:
Failed to load http://127.0.0.1:8000/signupAuth/: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
What should I do?
and an extra question: what happen in the given url in my axios?
just open your website with the same host url you are trying to call. Use http://127.0.0.1:8000/ instead of localhost
I have created an app with react native, where the user is able to log in with facebook. I request the users first_name, last_name and picture.width(520)(which is the users profile picture).
When the user log ins for the first time it works fine. In the profile section you can actually see the picture, however after a day or so if you log in again the profile picture wont load. In the database I can still see the same URL given to me by the request, it just wont load.
Does FB change the URL or how can I permanently get a URL that points to the users profile picture?
The actual request:
const infoRequest = new GraphRequest('/me',
{
parameters: {
fields: {
string: 'first_name,last_name,picture.width(520)'
}
}
}, (error, result) => {
//save picture URL to database
})
I have a working python code on my desktop that prints and makes PDFs perfectly. All I want to do is use that code and use Django to allow users to enter a value.
My code uses docusign API to call data. I use postman which needs a key and other parameters to use the API. The value entered by my user will determine what data they get.
What I think I have to do is rewrite my code, put it somewhere, then turn it into a view. The view will be sent to template.
Edit -
My code:
# Get Envelope Data- use account ID from above
# Get Todays Date, Daily Setting
day = datetime.datetime.today().strftime('%Y-%m-%d')
url = "https://demo.docusign.net/restapi/v2/accounts/" + accountId + "/envelopes"
# if Envelope is completed
querystring = {"from_date": Date, "status": "completed"}
headers = {
'X-DocuSign-Authentication': "{\"Username\":\""+ email +"\",\"Password\":\""+Password+"\",\"IntegratorKey\": \""+IntegratorKey+"\"}",
'Content-Type': "application/json",
'Cache-Control': "no-cache",
'Postman-Token': "e53ceaba-512d-467b-9f95-1b89f6f65211"
}
response = requests.request("GET", url, headers=headers, params=querystring)
envelopes = response.text
Sorry, let me try again. I currently have a python3 program on my desktop. I run it with idle and everything is how I want it.
What I want to do with Django is use this code to print its outputs on a webpage and have the user download it’s additional csv file output. I have managed to make a Django localhost and I am stuck at that point. I do not know how to use my python3 code to run to webpage.
The code is made up of API calls, I use postman to help me with sending the right parameters. I will add a picture of code. All I want is for user to enter value such as accountID so that the API can complete the request and give them data for their own request.
I'll try to give you a overview of how this could work with Django.
You could have a form to obtain the users account_id.
class AccountForm(forms.Form):
account_id = forms.IntegerField()
You could display this form through a generic FormView (see also this):
class AccountView(views.FormView):
form_class = AccountForm
template_name = 'account.html'
def form_valid(self, form):
# here you make your request to the external API
account_id = form.cleaned_data['account_id']
url = "https://demo.docusign.net/restapi/v2/accounts/" + account_id + "/envelopes"
headers = ...
querystring = ...
resp = requests.request("GET", url, headers=headers, params=querystring)
ctx = {
'result': resp.text,
}
return render(self.request, 'result.html', ctx)
I don't show the template account.html here. You will have to figure that one out yourself; the links I provided should point you in the right direction.
Now, what remains to be determined is what exactly the method form_valid should return. The code I showed renders a template with the API call response in the context, so in your template result.html you could display the result data any way you like.
You mentioned downloading a CSV file as well. That could be a different view, probably triggered by a link or button in result.html.