Django: 2 active users in a specific url - django

I simply don't know how to do it.
I have an html linked with a knew url, with two buttons.
imagine that url is only shared with two persons/users.
each person have to push the button signed their name.
I tried using request, but I couldn't figure out how to know if more than one user is active in that view.
The another point is:
One person reach the url first, how to make an "refresh" in their browser, when the second one appear?

You'd have to store who's at what view in some model.
class UsersInURL(models.Model):
users = models.ManyToManyField(User)
url = models.CharField()
# you'd probably want to use a through table and set up some expiration logic
Then remember to modify this model every time a logged in user views a page; middleware sounds perfect for this.
class UserTrackerMiddleware(object):
def process_view(self, request, *args, **kwargs):
UsersInURL.users.through.filter(user=request.user).delete()
users_in_url, created = UsersInURL.objects.get_or_create(url=request.path)
users_in_url.users.add(request.user)
Then to refresh their page, you'd need to set some kind of communication between the server and the browser which pings this model and refreshes if it detects some change.
var lastCheckedUsers = undefined;
function checkForNewUsers() {
$.get('/some-ajaxy-url/', { url: document.URL }, success: function(data) {
// you'd have to set up a view that returns active users # url
if (lastCheckedUsers != data.users && lastCheckedUsers != undefined) {
window.location.href = window.location.href;
};
lastCheckedUsers = data.users; // store last state; refresh if modified.
})
};
setInterval(checkForNewUsers, 1000);
I'm sure that should get some ideas flowing.

Related

Django - Prevent admin action to run twice

My problem is simple, I have an admin action named "send email":
The problem is, the admin user can call this function twice in a row, probably by clicking "Go" many times; this causes the email to be sent multiple times. Is there a way to prevent it?
I tried to put a timeout in the end of the admin function send_email but it's not working: it takes 10 seconds between each users, and I have many users.
def send_email(modeladmin, request, queryset):
...
time.sleep(10)
You can use JavaScript to prevent double clicking on the button.
To add javascript to your admin, you can override the admin HTML templates or adding a javascript using this approach
const button = document.querySelector("#my-go-button");
let didIClickGo = false;
button.addEventListener("click", (event) => {
if (!didIClickGo) {
didIClickGo = true;
} else {
event.preventDefault();
}
});
Note: on line 1, point the selector to your button.
Another option would be rate-limiting on the backend where you would save the data about the emails and whenever you call the function, you should check if you sent an email to this user in the last couple seconds maybe.
You can check if the queryset is different from the last time to avoid calling send_email twice in a row:
old_queryset = None
def send_email(modeladmin, request, queryset):
if self.old_queryset != queryset:
self.old_queryset = queryset
... # Inserts your code here in the "if" block
You must define old_queryset as a property of the ModelAdmin subclass.

serializer.save() not saving data to admin database

So, i was making a simple Web app in which i would get in data from user using React JS Front-end Interface and Forms. Django stays in the background where i have made CRUD functions.
My app lets user to create, edit, delete and view the data inputted.
Edit and View work perfectly fine but create has been making a problem for me. There is no error in the browser console or django terminal but the React JS front-end change does not reflect in the Django Admin.
Now, handleChange simply listens to the change made in the HTML form. Active Record is my current form in which new data is being added:
handleChange(e){
var value = e.target.value;
this.setState({
activeRecord:{
...this.state.activeRecord,
[e.target.name]:value
} }) }
handleSubmit() just connects my frontend submit button to Django's CRUD'S Create url. Finally, i set the current object state back to default.
handleSubmit(e){
e.preventDefault()
console.log('Item',this.state.activeRecord)
var csrftoken = this.getCookie('csrftoken')
var url = 'http://127.0.0.1:8080/DataCollection/create/'
fetch(url,{
method:'POST',
headers: {
'Content-type':'application/json',
'X-CSRFToken': csrftoken,
},
body:JSON.stringify(this.state.activeRecord)
}) .then((response)=>{
this.fetchTasks()
this.setState({
activeRecord:{
id: "",
full_name:"",
age:"",
gender:"",
weight:"",
height:"",
salary: "",
project_count: "",
job_domain: "",
experience: "",
no_of_jobs:"",
}
})
}).catch(function(error){
console.log('ERROR',error)
})
}
handleSubmit() just connects my frontend submit button to Django's CRUD'S Create url.
Please note that there is no error shown when i run it but 2nd line console.log in the handlSubmit() function shows the inputted values implying that my added data is reaching react js at least.
Thus, this makes me think there is some issue with the Django part and hence, i have posted this question in this subreddit.
Note: I am an aspiring data scientist who is to start his Master Studies in September 2020. Just wanted to add some Web App Development skills to my resume.
Any suggestion would be appreciated....
Create View:
#api_view(['POST'])
def createRecord(request):
serializer = InputValuesSerializers(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
b.) Serializer: serializers.ModelSerializer had to be this way. Got a gruesome error when i tried to use serializers.Serializer
class InputValuesSerializers(serializers.ModelSerializer):
class Meta:
model = InputValues
fields = 'all'
I've tried all the online resources and discussions but cannot find the solution. This is really frustrating as i can that the data is going where it's supposed to go, but only a single statement might me screwing things up.
I would really appreciate any help over this.

Django sending context to multiple views

I'm trying to achieve following tasks in Django:
First page: User fills a large Job application form and that data is
sent to Second page
Second page: User reviews his previously filled data and proceeds to third page
Third page: User pays the amount(came from Second page) and once paid, then only all this data is saved to DB.
I've done First page work of filling form and then sending that data to Second page.
Here's my views.py
def applyJob(request,id=None):
job = get_object_or_404(AddJob, id=id)
if request.method == 'POST':
context = {
'jobName': job.jobName,
'jobID' : job.pk,
'cfName' : request.POST.get('candidateFirstName'),
'cmName' : request.POST.get('candidateMiddleName'),
'clName' : request.POST.get('candidateLastName'),
......
return render(request,'reviewAppliedJob.html',context)
else:
context ={
"jobName": job.jobName,
"id": id,
}
return render(request,'applyJob.html',context)
Since I'm sending the context data using return render(request,'reviewAppliedJob.html',context), URL is not changing and so it's not going to my reviewAppliedJob views and so I cannot write code to go to Third page.
def reviewAppliedJob(request):
return HttpResponse('done....')
For that, I can use HttpResponseRedirect('/reviewAppliedJob') instead of render in applyJob() but it will not send my context data. Django allows sending context either using render(), messages framework, url params or session. But since I have large amount of data, I don't know which one to use and will work perfectly.
What's the best way to achieve this task efficiently and securely?
Thanks in advance.
I suggest you use sessions instead. Instead of writing three individual views you can write one. After user fills the data, save them in a session key with a phase key temporarily. In this way, when the view is processed you can access to data and phase of the user.

Django: call REST API through a view instead of Postman

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.

Fallback for Django view that relies on session variable

I have a view that looks like this:
def CineByCiudad(request):
city = request.session["ciudad"]
cines = Cine.objects.filter(ciudad=city)
context = {'cines': cines}
return render_to_response('cine-ciudad.html', context, context_instance=RequestContext(request))
Now, I am using the session variable "ciudad" to filter my query.
On the homepage of my site I let the user set their "ciudad" and once its set I redirect them to another page and they can start viewing the content based on their city("ciudad").
My homepage checks if the session has items:
def index(request):
#Checks to see if the session has items, in particular if a city has been set
if not request.session.items():
return render_to_response('index.html', context_instance=RequestContext(request))
else:
return redirect(Cartelera)
Now lets suppose for some reason the user deletes his cookies and on the site he visits a url different than the homepage(something like www.site.com/cartelera) he would then get an error because the session variable "ciudad" is not set.
Is there a way to create a default value for this session variable in case that it has not been set?
Or what is a good practice to deal with this issue?
Use the dict.get method on the session to retrieve a default if the value isn't set, like this:
city = request.session.get('ciudad', 'default value')