Web API and rendering template, should they in the same function call? - python

I am new on web development.
I am now implementing a simple create/edit user form with a submit button.
I would like to know the better practice to implement this.
I have already define this kind of web api
URL Method Description
/users/ GET Gives a list of all users
/users/ POST Creates a new user
/users/<id> GET Shows a single user
/users/<id> PUT Updates a single user
/users/<id> DELETE Deletes a single user
My first approach:
i create two new "/user/add" and "/usr/edit" function,
which similar to
app.route("/users/edit")
def edit_user(){
....
....
call the internal api /user/ with a "put" method
....
render_template("edit.html")
when I click the submit the button, the i call the above internal api /users/ ,method=PUT,
and render the final template.
My second approach:
in my internal api /user/, i try to read the http header to see if i want a html template or json text and return back to user
Say, again when i want to create a edit form, instead of calling /user/edit , i call /user/, with a PUT method
def put(self, id):
//see the header of that request
if header == html
render_template("edit.html", .....)
if header == json
update the record
#
my question , basically, i don't know if "/user/add" "/user/edit" route is necessary to make a form, or we can just simple embedded into /user/ api with different "post" or "put" method.
the idea is coming from here , from flask, pluggable view, which i am wondering how to make a better implementation
Or is that a better way to do it???
Thanks a lot.

I would choice your first approach because than your URLs are clear and logical. Also you split your frontend (Website with forms) and backend (API) which is in testing very helpful. A normal web browser makes only GET and POST requests to a website so it is very difficult to render template by a PUT request for the user because the user is normally not able to start a put request.

Related

Django - beginner- what is the process for passing information to a view via a url?

I am working on my first django project which is also my first backend project. In the tutorials/reading I have completed, I haven't come across passing information back to django without a modelform.
My intention is to calculate a value on a page using javascript and pass it to django when a user hits a submit button on that page. The submit button will also be a link to another page. I know I could process the information in a view via the url if I knew how to pass the information back to django.
I'm aware that django uses MVC and as I have my models and views in place, I am lead to believe that this has something to do with controllers.
Basically, I would like to know how to pass information from a page to django as a user follows a link to another page. I understand that this isn't the place for long step by step tutorials on specific topics but I would appreciate any links to resources on this subject. I don't know what this process is even called so I can't search documentation for it.
EDIT:
From further reading, I think that I want to be using the submit button to GET or POST the value. In this particular case, POST is probably better. Could someone confirm that this is true?
Yes, generally POST is a better way of submitting data than GET. There is a bit of a confusion about terminology in Django. While Django is, indeed MVC, models are models, but views are in fact controllers and views are templates. Since you are going to use AJAX to submit and retrieve the data, you don't care about templates. So what you most likely want is something like this
in your urls.py as part of your urlpatterns variable
url(r'mything/$', MyView.as_view())
in your views.py
from django.views import View
from django.http import HttpResponse
class MyView(View):
def post(self, request):
data = request.POST
... do your thing ...
return HttpResponse(results)
and in your javascript
jQuery.post('/mything/', data, function() { whatever you do here })
There're many ways, you can achieve this in django. Following are the two ways, that I generally prefer :-
1) As a query string parameter in the URL
eg. http://localhost/getPatientInfo?patientId=23&name=Sachin
2) Making URL dynamic, to include the information in the view itself.
eg. http://localhost/patientInfo/23/Sachin
In case 1:-
You will have to do,
patientId = request.GET["patientId"]
name = request.GET["patientName"]
In case 2:
Your URL conf will be something like :
urls = [
url("^patientInfo/(\d+)/([^/]+)$", yourViewFunc)
]
And in your view func :-
def yourViewFunc(request, patientId, patientName):
# your logic goes here
pass
For info. related to URLConf, refer to https://docs.djangoproject.com/en/1.10/topics/http/urls/#example

DJango: redirect form data, or pass form data to another view

I have a form that needs to process some data in my django app, before the form data is passed to another app.
Is this possible? If not, how might I handle this situation?
Here's a more detailed example of what I need to do. Any suggestions on HOW to accomplish this are welcome!
I have a comments app that tracks comments and replies on arbitrary objects, provides notifications, nested commenting, etc. I'm trying to keep this app generic.
I have another app called "submissions" that uses the comments app. A student enters a submission (via a CommentForm from the comments app) and the results are sent to the comments app which handles it.
In this case, I have two submit buttons on the form: Approve & Return
Regardless of which button is hit the comment app will handle the data the same. However, my submissions app needs to do stuff based on which button was pressed.
The first way I thought of doing this was to pass the form to a submissions app view first, then redirect to the comments app, but I don't think the form data will come with it.
The second way was to only pass it to a submissions app view, then call a function in the comments app, e.g. Comments.objects.create_comment(...) instead of a view to handle the data, but I'm not sure how to pass the form data.
This remembers me very much of this question: django - how to implement a 2-step publish mechanism
You can use the session to save your data after you're done in step one (the submissions app, if I get you correctly), and then redirect the user to step two where they have to submit again (or just redirect again - that'd be a chain, so a bit of a minus there, but works).
Another possible way would be to hack/read a bit into the guts of the comments app to use its interna in the submissions app, so you combine both functionality into one view/function. But I can't help you with that without knowing the code (and it's your project after all, so it's your task).

Redirect to new url from flask form

I'm using flask to make a scheduler app. I have a function that will take a list of college courses from the url and schedule them. Is there any way to make a form that people could enter the classes in as opposed to using the url?
My view function:
#app.route('/sched/<some_list>')
def scheduleMe(some_list):
course_list = some_list.split(',')
my_combos = scheduler.schedule(course_list)
return render_template("sched.html", title="Scheduler", combos=my_combos)
takes in a list of courses such as BT 353,CS 135,HHS 468,BT 181,CS 146,CS 284 and returns a page with all the possible schedules for those courses.
I'm trying to make some sort of form where if a user entered the courses above it would redirect them to www.mysite.com/sched/<courses they enter>. I was going to use GET and then basically make a view function that was take the resulting url from the form and pull the courses out of the query.
Is there a better/ more direct way to do this?
Thanks!
This might not be the best way to answer a question on stackoverflow. Flask does provide a redirect option to another url. Also check url_for. For more on forms, you can look here.

Implementing Universal Search in a Django Application

We have a large Django application made up of a large number of different views (some of which contain forms). As with most large applications, we use a base layout template that contains the common layout elements across the applications (mainly a header and a footer), which the templates for all of our views extend.
What we are looking to do is create a universal search box in our application, accessible on every page, which allows users to perform searches across the entire application, and want to place the search box inside the header, which involves placing a form inside our base layout template. This means that every view in our application will need to be able to handle the submission of this search form. Once this search form is submitted, we will need to redirect the user to another view containing the search results.
However, we are struggling to come up with a pattern to handle this. Does anyone know of functionality built into Django that will help us to build this? Failing that, can anyone suggest a good strategy for modifying our application so that we can handle this use-case without having to modify a large number of existing views (which we don't have the resources to do at the moment)?
Please note that the focus of this question is intended to be the best way to handle the submission of a form which appears in every view, and not strategies for implementing a universal search algorithm (which we have already figured out).
Ideas Explored So Far
Our first idea was to create a base View class that implements handling the universal search form submission, and have each of our views extend this. However, this is not possible because we already have views that inherit from a number of different Django view classes (TemplateView, ListView, FormView and DeleteView being some examples), and to be able to build our own common view class would mean either writing our own version of these Django view classes to inherit from our own view base class, or re-writing a large number of our views so they don't use the Django view classes.
Our next idea was to implement a mixin that would handle the universal search form submission, in an attempt to add this functionality to all our views in a way that allows us to continue using the different Django view classes. However, this brought to light two new problems: (a) how could we do this without modifying each of our views to become a form view, and (b) how can we do this in a way that allows the form handling logic to play nicely when mixed in to existing FormViews?
This seems like such an obvious question that maybe I'm overlooking something. But as others have said your universal search form should not make a POST request to the view that rendered the current page.
Each html form has an action attribute. The attribute of your search form should point towards an URL. Probably something like /search. That url would have a view behind it that handled the POST request from the form and returned the search results. Django has URL template tags to make this easy. {% url 'myapp.views.search' %} will give you the correct url for the search view function if it lived inside the views module in myapp. So the relevant bit of html in your base template would be something like:
<form action="{% url 'myapp.views.search' %}">
<input type="text" name="qs" placeholder="Search">
</form>
If you are planning on displaying the search results on a new page there is absolutely no need to return JSON or anything like that. Just have a search view that looks like this
def search(request):
query = request.POST.get('qs', '')
results = SomeModel.objects.filter(name=query) # Your search algo goes here
return render(request, 'search_results.html', dict(results=results))
Instead of handling the form submission on every view of the application, you can implement a separate view (endpoint), which handles all the search queries. (an endpoint which returns JSON result) since you dont want to add overhead of rendering the whole page with that view. So the search query (which client side AJAX performs to the webserver) will return JSON response, and the Javascript can render that response. This way you can keep the search view isolated from the rest of the views. (Django REST will be helpful in this case)
And this search form will be included in your base template, so your search box is accessible from the entire application, and it submits to the same view. And the AJAX function will handle the server response for rendering it.
It seems like you just need to create another SearchView which takes the query and displays the results. I am not sure if the results have to be displayed differently depending on which page the search has been performed from but it does not seem like.
The form would not have anything to do with the other views. You could just hard code it in the base template.

Distinguishing post request's from possible poster elements

So, what issue im running into is how do i know what element of my page made a post request? I have multiple elements that can make the post request on the page, but how do i get the values from the element that created the request? It seems like this would be fairly trivial,but i have come up with nothing, and when doing quite a few google searches i have come up with nothing again.
Is there any way to do this using Bottle?
I had an idea to an a route for an sql page (with authentication of course) for providing the action for the form and use the template to render the id in the action, but i was thinking there had to be a better way to do this without routing another page.
You could add a hidden input field to each form on the page with a specific value. On the server side, check the value of this field to detect which form the post request came from.

Categories

Resources