call internal view function in django - django

I want to call a function from another function in django. The function looks like this
def main_view(request):
if request.method == 'GET':
I dont want to have the url to main_view open so that user can access this url directly, instead they should face a login page(just a lot of checkboxes that the four right ones should be choosen) and after that submit, they should come to the template that the main_view function is rendering.
But, how do I actually call function internal that need a request GET input?
Is there a way to do a GET request when calling the function?
//Mikael

You can just pass the request from your other view into that one, like this:
def my_public_view(request):
if user_passed_checkbox_test():
return main_view(request)

Related

How to get url params from the HttpRequest object

Suppose, we have a url path:
path('something/<int:some_param>/test/', views.some_view)
When a user hits this url, django makes an instance of HttpRequest, that will be passed to the some_view view. Is there a way to get the some_param url parameter from the request object outside the some_view code? (for instance, to do some processing that depends on some_param in a custom middleware).
One possible solution is to parse the HttpRequest.path attribute, but is there any prebuilt way to do this?
Django calls your view with the request object and some_param, which you have access to inside views.some_view. Your function will have the following signature:
def some_view(request, some_param):
....
Or:
def some_view(request, **kwargs):
some_param=kwargs.get('some_param', None)
You can then use some_param inside your view to do whatever you need to do with it, save it in a database, put it in a cookie, do calculations with it, get some database data with it, etc. Then once you're done, you need to return a response object. Usually by calling render or TemplateResponse with a template or returning HttpResponse without a template. You render templates providing a context dictionary which you are free to put anything you like into (like some_param), which makes it available to be rendered in your HTML template. That rendered HTML template is then returned as response to your user through the magic of the render function or TemplateResponse class, which ends the view process. I.e. like so:
return TemplateResponse(request, 'template.html', context)
To store some_param in between views, you'll need to save it in the database, store it in the user's session, or use a cookie. Or pass it to the next view inside the url or outside the url via /?param=some_param. Without saying what you need some_param for later on, it's hard to solve your issue.
The one possible solution here is to use the resolve function from django.urls module. It is extremely uselful if you want to access the URL parameters from URL path that is related to a HttpRequest object outside a view function. For example, get the URL params and process them in the custom middleware or other parts of your code.
Example:
from django.urls import resolve
...
func, args, kwargs = resolve(some_request.path)

Call stored procedure in Django

I am trying to call a stored procedure in Django that returns some data based on which batch number you give it. In my database if I write
call InkItUp.InkBatchNumberCallBackk(15137);
I return the data I need. But then I try to use Postman to call the URL I have defined for the view saveInkbatch in my urls.py file It gives me this error:
The view api.views.saveInkbatch didn't return an HttpResponse object. It returned None instead.
Me urls.py look something like this:
path('createsp/', views.saveInkbatch),
and there is the method in the view.py
#csrf_exempt
def saveInkbatch(request):
if request.method == 'POST':
if request.POST.get('batchnumber'):
save=Ink()
save.batchnumber=request.POST.get('batchnumber')
cursor=connection.cursor()
cursor.execute("call InkItUp.InkBatchNumberCallBackk('"+save.batchnumber+"')")
messages.success(request, "The batchnumber "+save.batchnumber+"")
return HttpResponse(request, content_type = 'application/json')
If you know a way to call a stored procedure from MySQl with a class-based view - It would be nice to. I would much rather use class-based views if possibly.

Django run a function while exiting a view or navigating to a different URL from the current URL

In my django application, when I visit a particular URL ex:enter_database, a view function is called that adds database entries. Now when I visit a different URL, I want to clear the database entries.
My question, is it possible to call a method while leaving a view/URL.
Note: I can clear the entries by adding the logic in every other view, which is not the approach I want to do. I am looking for a way to call a method while exiting the current displayed view.
In the end of your view you have to create response object and return it.
So I don't know is a correct Django way or not, but you can create custom reponse class and insert logic inside here
class HttpResponseWithDataClearing(HttpResponse):
def __init__(self, content=b'', *args, **kwargs):
# Some custom logic here (clear the entries?)
super().__init__(content, *args, **kwargs)
After that change view's return statement
return HttpResponse(...)
↓
return HttpResponseWithDataClearing(...)
Where you want to add custom logic.
If you want to add logic when already response sent and you moving to another page, that is impossible to do at backend.
You must to set javascript action on page leaving. And do ajax request to data_clear_url
window.onunload = function() {
do_ajax_request("data_clear_url");
}
EDIT1: onunload method not working
I tried to reproduce javascript onunload method and looks like ajax request is not properly working with Chrome in this case. You can check this article

Django | Triggering a function from list in template

I'm trying to make a facebook like Newsfeed.
I have a Post which contains all post. After sending it from the view I load the posts to the templates with {% for p in posts %}, for each post I add 2 buttons (share, like) and an input (comment).
How can I know which of them was clicked so I can send the post.id back to the view, including the name, and value and trigger a function to handle them in the database?
I want to know after I click an input what was it, what it included and for which post it belongs.
The way I would have approached this is something as follows:
I would have specific views to handle share and like functionalities, I would rather have them as two separate views. For them you then create urls, definitely you will be also providing post identifier as a parameter to this url.
For eg:
class LikePost(View):
def post(self, request, post_id, *args, **kwargs):
code
For this class, you can then have a url like ^/post/(?P<post_id>\d+)/$.
Now for more simplicity in your Post model class you can write a model method that returns you the url for LikePost view for an instance of post.
Something like this:
def like_post_url(self):
return reverse('appname:reversename-for-url', args=(self.id,))
So now when you loop posts in template you can simply assign this url as value for href in anchor tag you use for button. So every button will have its own url for share, like and also for input.
I think this should make it clear on how you can proceed with simplicity.

Is making the request object optional for a view incorrect in Django?

Usually a Django view looks something like:
def exciting_possibilities(request, optional_variable=None...):
I have the case where the optional_variable is captured in the url via a regex. It's a user identifier, and only transmissible via GET as part of an email link due to specific business circumstances. If it's present, my_view dynamically chooses a "possibility". If it's not present, it renders an identifying form for the user to provide the info.
Let's say the user now POSTs the info to the form (simplified):
def identify_user(request):
e = ExampleUser(identifier=request.POST.get("optional_variable", None))
e.save()
Now that the user is identified, I want to now go back to exciting_posibilites, but obviously I can't just call:
return exciting_possibilities(optional_variable=e.identifier)
because there's no request (and generating one requires a URL, which I don't have).
Should I make request optional (with =None) and cut the "possibility choice" logic out into a separate function?
Or when returning from identify_user maybe should I pass the original request (even though it's a POST), and take the request.method checking logic out of exciting_possibilites?
This is where you do a redirect, from a POST view to a GET view. In this case, after form data is posted, just redirect to your exciting_possibilities view.
def identify_user(request):
e = ExampleUser(identifier=request.POST.get("optional_variable", None))
e.save()
return redirect(reverse('exciting_possibilities', kwargs={'optional_variable': e.identifier}))