how to overwrite django template render method handling - django

In my application, I am sending periodic cron and background task requests to refresh the cache of pages. While sending a force_refresh kwarg from the view is easy, there's no apparent way to send the force_refresh kwarg to methods being accessed from the template. There are plenty of these I'm using, and it would just make things more complex to start calling all these methods from the view.
So I've been trying to overwrite the template render method so that I pass in the force_refresh kwarg whenever a method is being accessed, if the given response is for a background task request.
I realize that it might simply lead to unexpected problems to add this kwarg to all methods being called, and a try/except ArgumentError block wouldn't exactly be a robust solution, if you have any recommendations about a better way to handle this (hopefully besides accessing each of these methods from the view!), it would be useful to hear them.

Sorry, but your use case is precisely what the view function is for.
In the view function you gather all the data. From this you create a dictionary of the latest data which will be used by the template.
All logic goes in the view. The template has minimal processing.

Related

Managing global objects in Django

Context:
I was going through various guides, tutorials and also posts here in the stackoverflow.
I need to handle process, e.g., - “pick topic —> show author list —> delete all —> ask confirmation —> show result —> go back to author list”
The obvious (and simplistic) approach is to create sets of views for each process.
And save process state in session variables or pass via URL-s (however, I discovered this method can be very brittle if too many information is passed). Also I need to tell each view where to go next, and this mushrooms into a bulky chain of instructions repeated for each URL request.
Instead, I want two extra things:
encapsulate a process at single place
re-use views, e.g. to re-use Topic List view to pick a single topic. That is, to work in “picker mode”. (btw, if I try to do this with multiple view classes, the next view class needs to know what to do and where to return…)
I also checked django workflow libs, and so on. and still not convinced.
Question:
if I create global object to encapsulate process and reference it from the current session - is this a good idea? My main concern is that - as sessions come and go, who will be cleaning up this global object?
is it possible to somehow make this clean up automatic? that is, when session goes away, some method is called where I can clean up or help GC to collect unneeded object? Like C++ destructors?
after working further with code, it occured to me that if I add global object to the session (and nowhere else) - it must be garbage collected in due course, because session itself is managed by Django.....
also, reading https://docs.djangoproject.com/en/3.1/topics/class-based-views/intro/ in my 3rd pass, found that Django's as_view() instatiates a new instance of class based views on each HTTP request.
so, everything is per request basis, and data will be transient. So only way to maintain state across HTTP requests is to either persist in the database or use sessions (or keep passing "state" from each request to request via URL parameters, but it is bulky, unsafe. my understanding is that this is a fallback mechanism if cookies are not allowed and session can be simulated via this way, e.g. PHP does it).

How to prevent a Django view that calls an external api from being flooded when it is called by a GET request?

I am writing a Django application with a view that is passed GET parameters. This view contacts an external API to get information, and passes the consolidated information to a template. The external API call is costly and limited. I am concerned that in a production environment, an attacker could write a script to repeatedly load the page with different parameters, (as I'm caching requests, so repeated calls with same parameters are fine), to exhaust my ability to use the external API.
I am trying to ensure that only humans can load my view (or specifically, reach the point of the external API call), or, at least, that a robot can't load it hundreds of times.
The most elegant solution would be some code in the view before the API call that could validate the user somehow. If the user failed the validation, they could be referred to another view or to a different template with a failure message. I am trying to do this as elegantly as possible and not be sloppy, however, so I'm looking for advice on best practice.
Initially, I intuitively wanted to use reCAPTCHA, however, it seems that this is generally used for forms. Adding reCaptcha to the form that directs to this page would not solve my problem, since the attacker could just run the attack by modifying the parameters in the url. Is there a way, either properly or with a hack, to test the user with an invisible, (or possibly visible, but I don't want to deter people by making them fill out a captcha every time), re-captcha in the view? I can't think of a way to do this, but perhaps it's possible.
Hopefully there is some external service or library that I could use to make a simple call to some sort of validator, which at least will block or heavily throttle a user if they are spamming my site, and, at best, would use more sophisticated methods to tell.
The view structure:
def myView(request,query1,query2):
results = call_external_api(query1, query2)
return results to a template using context
Thanks for the help in advance, I hope I was clear in describing my problem!

Application logic in view code

Should I be writing application logic in my view code? For example, on submission of a form element, I need to create a user and send him an activation email. Is this something to do from a view function, or should I create a separate function to make it easier to test down the road? What does Django recommend here?
I found it very hard to figure out where everything goes when I started using django. It really depends on the type of logic you are writing.
First start with the models: model-methods and managers are a good place to perform row-level logic and table level logic i.e. a model manager would be a good place to write code to get a list of categories that are associated with all blogposts. A model method is a good place to count the characters in a particular blogpost.
View level logic should deal with bringing it all together - taking the request, performing the necessary steps to get to the result you need (maybe using the model managers) and then getting it ready for the template.
If there is code that doesn't fit in else where, but has a logical structure you can simply write a module to perform that. Similarly if there are scraps of code that you don't think belong, keep a utils.py to hold them.
You shouldn't perform any logic really in your templates - instead use template tags if you have to. These are good for using reusable pieces of code that you you neither want in every request cycle nor one single request cycle - you might want them in a subset (i.e. displaying a list of categories while in the blog section of your website)
If you do want some logic to be performed in every request cycle, use either context processors or middleware. If you want some logic to be performed only in one single request cycle, the view is probably the place.
TLDR: Writing logic in your view is fine, but there are plenty of places that might be more appropriate
Separating the registration code into it's own function to make testing easier is a good reason. If you allowed admins to register users in a separate, private view, then a registration function would be more DRY. Personally, I don't think a little application logic in the code will do to much harm.
You might find it instructive to have a look at the registration view in the django-registration app -- just to see how it's written, I'm not saying you should or have to use it. It has encapsulated the user registration into it's own function (there's a level of indirection as well, because the registration backends are pluggable).

where do functions that don't display go in django

I have some links on an html page like , , currently I handle them as so
<p> rate down
and have a url.py entry:
(r'^cases/(?P<case_id>\d+)/case_rate/(?P<oper>.)$', 'mysite.cases.views.case_rate'),
then I have a view function that handles the logic and hits the DB, then does this:
return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
I's there a better way to do this? I can see how this would be OK because it does have to redraw the screen to show the new rating...
The typical way to handle this is with an ajax request.
Instead of a link, you put a javascript handler that calls a view, wich updates the db, and returns a json / xml object with the new rating for the item. Then another javascript handle receives that response and updates the rating number on the screen, without a page reload.
Ideally, you'll keep both versions: plain html (the one you currently have) and the ajax one. The ajax one can be attach to the element after page load, so if javascript is not available, you'll still have a working site.
Then, regarding organization, you can have an "ajax" parameter on your view. The view should update the db accordingly, and if it's an ajax call, return the json / xml response, otherwise, return the new page. That way you can keep the logic (fetching the object, updating the db) on one place.
If you're asking whether case_rate should still go in the views.py given that it returns a redirect rather than providing content, the answer is yes, since case_rate is handling an request and returning a response.
But consider a situation where you had two view functions in views.py that had some duplicate code, and you chose to factor that duplicate code into another function that didn't both take request and return a response. Would that be fair game to leave in views.py? Sure, if moving it elsewhere would make the code harder to read. Or you might choose to put it elsewhere. It's really your call based on your sense of taste.

Dynamically include template elements from other apps in Django

App_1 has a view and a template for this view. It would like to "aggregate" information into this view from other sources (i.e. other apps), without having to add or change anything itself. Perhaps App_2 wants to put "hello world" into this designated area in App_1's view. What is the best way of achieving this?
Signals come to mind naturally. But what should signal receivers send back? In my mind, App_1 template includes a custom tag that sends a signal and receives a list of templates (e.g. 'app_2/template.html') back, and it will register each one. However, it seems like inclusion_tag only supports 1 template rendering for each tag.
What recourse do I have?
I ended up doing what I described, but without the default inclusion_tag support. I made a custom tag that sent signals, collected template names, and created a Node that renders each template in series and concatenates the result. This seems to work fine, and has the same logic as the inclusion tag shebang.
I hope I'm understanding right, but it would seem that your solution to this problem is in your second sentence: 'aggregate'. The view function in App_1 should aggregate, or collect, all of the necessary data, then pass it to the template via a context variable.
I think the question that needs to be resolved is: How does the view function know which data to aggregate?
Typically a view function is coded ahead of time with a knowledge of which data it needs to use. For example, a calendar app might be hard-coded to fetch Event model objects and pass those to the template (via context). In your case however, it seems that the data coming into App_1 is completely arbitrary and not previously defined.
You mentioned signals, but I think the problem that you're going to have here is that signals only give notification that an event has occurred. They don't allow the reeving function to pass data back, nor does the code that emits the signal wait for all of the signal receivers to finish processing before it continues.
Instead perhaps you could establish a registration system. App_ 1 maintains a list of something. The other apps 'register' items to that list and when the view function in App_1 fires, it turns the list into usable data, then passes it to the template via a context variable.