I have a page that has a simple form. When I submit this form I am redirected to the same page with the new objects created. I'd like to add inline links to the right of every object created to delete and edit. Would I do this with django or would I use javascript/AJAX to handle this? I'm just a little confused on the approach that I should take. Any suggestions?
Here's what my view currently looks like:
def events(request):
the_user = User.objects.get(username=request.user)
event_list = Event.objects.filter(user=the_user)
if request.POST:
form = EventForm(request.POST)
if form.is_valid():
form.save()
else:
form = EventForm(initial={'user':the_user})
return render_to_response("events/event_list.html", {
"form": form,
"event_list": event_list,
}, context_instance=RequestContext(request))
Usually, you would write another view function, e.g. delete_event(request, event_id) and wire it up in urls.py. Inside the delete view, you would use the provided Model.delete() function to remove the object from the database.
The choice whether to use ajax or not is mostly a matter of taste - you would need to issue a request via javascript to a similar function as I described above, which would take care of the logic.
Some additional overhead is present (when using ajax) in terms of updating the page appropriately.
The proper http verb for deletes would be DELETE, but since this is not usually supported out of the box, you'll use POST.
Related
I found one question similar to this, but not sure the solution is the best (it doesn't seem very DRY) and it is quite old so I hope its ok that I ask another one.
I have a django project with various pages that require you to be logged in to view them. It is quite simple to get django to redirect to a login page if you are not logged in but what I would like to do is to bring up a modal login with javascript. Obviously I could go through each link and determine manually whether it required login and assign a class to those links or something but I think there must be a better way.
I was thinking possibly along the lines of replacing the built in url template tag with my own that checks if the view is login required (not sure if this is possible) and then if it is, replaces the url with something that can be recognised by javascript to assign a click handler to bring up the modal. Ideal solutions would somehow allow for people without javascript to still be redirected to the login page.
Am I asking too much?
UPDATE
Ok, have come up with some basic code so I'm hoping that might encourage someone to point out where I am going wrong/right. I think that you probably can't check whether a view is login_required with a template tag and so perhaps a decorator for the views is the best option.
#decorators.py
def AJAX_login_required(view_func):
#wraps(view_func)
def wrapper(request, *args, **kwargs):
if request.is_ajax():
if not request.user.is_authenticated():
return HttpResponse(json.dumps({'login_required': True}), mimetype='application/json')
else:
if request.user.is_authenticated():
return view_func(request, *args, **kwargs)
else:
path = request.get_full_path()
login_url = reverse('login')
return redirect_to_login(path, login_url, 'next')
return wrapper
#views.py
#AJAX_login_required
def view_which_requires_login(request):
//etc.
def view_that_does_not(request):
//etc.
#javascript
$('a').click(function(e) {
var link = $(this).attr('href');
$.ajax({
type:"POST",
url:link,
data:'',
success: function(response){
if (response.login_required) {
//open modal login
return;
}
else {
document.location.href = link;
}
},
error: function(){
document.location.href = link;
}
});
});
I think this should result in what I want but it does require that every page that doesn't require login be effectively sent twice. Once to the ajax query and then again when the page is redirected. Is there a better way?
In terms of a better way... you could create a view that keeps a list of all your login required (or non-login-required) views. Issue an ajax call to that view, which would send a lightweight json message back. Saves your user the bandwidth, if not your server overhead.
Question is, how do you do get and keep the information? I'd try using decorators that register the view functions with a library. (This pattern is common in Django itself, see the admin and template tag system.) Make sure your library object always has a count and stashes it in the database or the cache. Don't compile it on the fly-- sounds like a good manage function.
I am having a hard time deciding on an appropriate way to Perform some server side functionality and then redirecting to the same View in my ASP.Net MVC project.
I am trying to call an Action after the selected index changed client side event of my combobox.
One way I can think of is to change the window.location to the url of my Action and pass the data i need via the query string like this
function SelectedIndexChanged(s,e)
{
window.location.href = "/MyController/MyAction?" + s.GetValue();
}
I also see lots of people saying you should use jquery ajax for this
function SelectedIndexChanged(s,e)
{
$.ajax({
url: 'MyController/MyAction',
data: { value: s.GetValue() },
success: function(){
alert('Added');
}
});
}
My Action looks something like this where i set some cookie values using the value and Set View bags values depending on the selected index.
public ActionResult SelectedIndexChanged(string value)
{
//Do some processing
//Set cookie values
SetViewBags(value);
return Redirect(Request.UrlReferrer.ToString());
}
Is there a better approach to accomplish my task, I am leaning more towards changing the location.href as it is simpler, but i'm not sure if this is good practice?
EDIT
To Clarify this Combobox is a Devexpress MVC extension so I will have to handle the "SelectedIndexChanged" client side event.
This Combobox is also on my layout page so it appears on every view in my project. So when it is changed i will need to to call the same Action no matter what page it is on
As you've indicated that your form is in your layout (not a view), I recommend you look at using a view partial. Fortunately, MVC has already provided an example with their view partial (can't remember the name) that has the login and logout buttons. If a user clicks logout, some javascript is fired and the form is submitted. This will redirect the user; however, you could also send the original address (referrer) as a parameter to your server method and then redirect to that page afterward.
You could always use an Html.Action
function SelectedIndexChanged(s,e)
{
#Html.Action("ActionName", "ControllerName", {optional route values})
}
I'm interfacing with a site that implements delaying a page-load with client-side JavaScript. Basically, a form is submitted on PageA.asp, and instead of the data going to PageB.asp, it goes to PageC.asp. PageC.asp consists of a 'please wait' message along with the following JavaScript:
function OnTimer() {
window.location.replace("PageB.asp");
return;
}
setTimeout('OnTimer()', 10000);
The interesting thing here is that when PageB.asp loads, it somehow has all the information submitted from PageA.asp. Yet whenever I've looked up whether you can pass POST data along with window.location.replace, the answer has been "no".
So how does PageB.asp have the data from PageA.asp even though it was loaded from PageC.asp? Does window.location.replace load the new page with the same POST data? How would I best re-implement this in mechanize: remember the POST data from PageA.asp and submit the form with the action being PageB.asp instead of PageC.asp?
Hello people
I'm trying to figured this out, but I still can't do it.
I have a rails 3 app, I'm working with invoices and payments. In the form for payments I have a collection_select where I display all the invoices number (extracted from a postgres database), and what I'm trying to do is when i select an invoice autopopulate others text_fields (provider, address, etc.) without reloading the page, in the same form.
I know I should use ajax, js, jquery, but I'm a beginner in these languages, so i don't know how or where to start
hope you can help me... thanks
What you are going to want to do is route an ajax call to a controller, which will respond with json containing the information. you will then use jquery to populate the different fields.
In your routes:
get "invoice/:id/get_json", :controller=>"invoice", :action=>"get_json"
In your invoice_controller:
def get_json
invoice = Invoice.find(params[:invoice_id])
render :text => invoice.to_json
end
In your invoice model (if the default to_json method is not sufficent):
def to_json
json = "{"
json += "id:'#{self.id}'"
json += ",date_created:'#{self.date}'"
... //add other data you want to have here later
json += "}"
end
In your javascript file,
$("#invoice_selecter").change(function(){ //calls this function when the selected value changes
$.get("/invoice/"+$(this).val()+"/get_json",function(data, status, xhr){ //does ajax call to the invoice route we set up above
data = eval(data); //turn the response text into a javascript object
$("#field_1").val(data.date_created); //sets the value of the fields to the data returned
...
});
});
You are probably going to run into a few issues, i would highly recommend downloading and installing fire bug if you are not on google chrome.. and if you are, make sure you are using the development tools. I believe you can open them up by right clicking and hitting inspect element. Through this, you should be able to monitor the ajax request, and whether or not it succeeded and things.
I'm trying to build a Django app for inputting science data, but am running into problems coming up with an elegant way to describe the possible forms.
I have two models, HCameraImage and MCameraImage that inherit from an Image model. On the site, the user can fill in HTML forms that populate either of these two models. In another words, I'm using HCameraImageForm(request.POST) to populate the model. Once I send it over to the client side, I find myself having to manually keep track of what form type is being sent to Django by appending an imagetype to the POST data:
if request.POST['imagetype'] == "HCameraImage":
form = HCameraImageForm(request.POST)
form.save()
if request.POST['imagetype'] == "MCameraImage":
form = MCameraImageForm(request.POST)
form.save()
...etc
Is there a more elegant way to deal with this? Ideally I want to have some parent base class Image that lets me do:
i = Image()
i.loadFormData(request.POST)
where loadFormData calls the correct derived function.
You could construct a string to instantiate the correct form object. Something like this should work:
import myapp.models
form_class = request.POST['imagetype'] + 'Form'
form_class = getattr(myapp.models, form_class)
form = form_class(request.POST)
form.save()