Events in Django - django

This might be a very dumb question but I can't find an answer anywhere. I was wondering how do you handle events in Django. I've read the tutorial in their webpage and I cant find a sign of explanation or I'm missing it.
I work in ASP.NET webforms and the way to do that, as you probably know, is putting the event name in the ASP.NET control and calling a particular procedure. I know Django is a very different framework because it's MVC, but I have taken a quick view to a ROR tutorial and I think I've seen they use something similar to ASP.NET webforms, if I've understood correctly, something like embedding ruby code in the html interface and declaring an action there, which I suppose calls the respective function, something like this
<%= ..., action:'action1', ...%> ,which calls a function 'def action1:' in the controller, similar (only in that sense) to asp.net, but webforms doesnt render a view with the name of the function among other things.
So the question is simply that, how do you use events in Django. I hope I was at least a bit clear because it's difficult for me to ask these questions in english

I'm a former ASP.NET developer who switched almost entirely to Django, so I know exactly what you're asking about.
Probably the simplest way I can explain it is this: What you're thinking of as an 'event' would be a URL AND View in Django. Abstract down what you were doing in ASP.NET and it'll make sense -- You had a control, which was just an element on a page. That was mapped to an event, which was really nothing more than a function. So the model of what you're doing looks like this:
object > method
In Django, it's similar, but there's an extra step. ASP.NET automatically connected the object to the method. In Django, you'll need to do that yourself. You do so by creating a URL for that object (urls.py), and then assigning that URL to a view (views.py) which is really nothing more than a method. In Django the same model looks like this:
object > url > method
In many ways they're achieving the same end effect -- something happens and it's handled by a method on the server. Django is simply a bit more open and lets you configure how it happens (and requires that you understand that and handle it yourself).

This concept of control (TextBox, Button, etc.) and page events, in the way you describe, is not carried over to most other frameworks. This was all part of Microsoft's attempt to make the web development experience very similar to that of developing Windows applications -- for better or for worse.
For instance, in a WebForms application:
button.Click += Button_Click;
private void Button_Click(object sender, EventArgs e)
{
// handle action here
}
Would roughly correspond to something like (client-side, in a template):
<form action="/myaction" method="POST">
<input type="submit" value="Click me" />
</form>
Server side view:
def myaction(request):
if request.method == "POST":
# handle action here
pass
In other words, what you want to do in Django and indeed in other MVC frameworks is have unique "actions", or methods, on your controller classes (or view functions in Django). These actions generally respond to HTTP GET and POST requests.
If you want client-side events on your controls, you'll want to look at using a JavaScript framework such as jQuery.

You do this in the view, dependent on the values of the request.POST dictionary.
For example, say you have two buttons on the HTML form, one with name="submit" and one with name="add". Then, in your view, you can do:
if 'add' in request.POST:
# do add action
elif 'submit' in request.POST:
 # do submit action
This is exactly how the admin app manages the difference between the "Save", "Save and continue", and "Save and add another" buttons.

Related

Using Form Wizard with pages that have no forms

I am working on a Django project where I have about 7 pages all in order. Basically step 1 - 7. I would like for them to have some sort of navigation/progress bar above the content showing where they are in the pages and how much they have completed. The only thing I have found close to this is using Wizard Form. The only issue I run into with this is some pages do not have a form.
Page 1 = Pure text explaining information
Page 2 = Setup information
Page 3 = Form
Page 4 = Form
Page 5 = Information
Page 6 = Form
Page 7 = Completion/Thanks
Is it possible to still use the Wizard Form for this setup? Or is there a better method of doing what I am trying to accomplish?
I haven't used Wizard form, but they look decent. Here are a few things you can try:
The first way is complicated. From my experience, React libraries like Material-UI have support for a navigation bar, progress bar, and all sorts of transition effects. They are complicated to get started though, and I won't advise you to try this unless you had worked with React before.
The second way is sort of a cheat. If Wizard Form requires a form on every single page, you can use something like this to easily get by:
<form method="GET" action="">
<p>Put whatever you want here. Divs, text, whatever.</p>
</form>
As you might've noticed, it's a form with GET request with no actions and a submit button. In that sense, you can just treat this form as a regular division. If Wizard Forms requires just a form, you should get by with this trick.

django - Add another model without Popup

Is there any magic why to do this in admin panel of django?
Let me know
Off the top of my head, you could use JS to grab the popup link and load the HTML in a div on the page. But that means you need to override the admin template. This QA should be helpful.
It also means you need to capture the saving of the new house. So, when someone presses save, depending on the response, the div either closes or shows the errors WITHOUT refreshing th page. I'm not sure but I think you'll also need to override the admin view that does this to send back json responses.
OR
You could use JS to mute that link and call up your own url, which would allow you to create your own view with your own custom form that does this. This would give you a bit more control without having to hack away at the Admin functionality.
e.g /house/ajax_add
You'll need to refresh the options in the House dropdown though. So I don't think you can avoid extending the template, now that I think about it.
It seems like a lot of trouble, really. No magic way that I know of, but it's possible.
To avoid popups, you might want to look at https://github.com/FZambia/django-fm:
Django-fm allows to create AJAX forms for creating, editing, deleting
objects in Django. This is a very personalized approach to quickly
build admin-like interfaces.
A live example can be found on http://djangofm.herokuapp.com/.
I'm not sure how this integrates with the current admin site, but with some changes it should not be hard.

Django custom view of a third party app

Lets say I have installed a 3rd party app called 'articles', the app contains basic templates and views. And there is a view called 'home' to list articles.
I need to add a form within that view and of course the form variable is not in the default 'home' view. How should I go about adding the form variable to that view?
There are a couple of ways I can think of right now:
Create another app and create a custom view.
This seems crazy and I won't do it, but for the sake of possibility, add a context processor to add the form variable into the context.
Just wondering if anyone had this situation and what is the best approach for this?
well, you may want to try a Function Decorator to redefine the previous view function.
the context processor or the middlerware is not recommend because it's global and dirty.
another use way I can thing is use-defined tags. This may takes more affort and go against the origin design of the tags. But it seem to be a good way.

CFWheels - Multi-step form?

I am wondering how one would setup a multi-step form in CFWheels.
Clearly I would need to store form data in the session etc as I go, but I would like to know the best approach from a wheels perspective to do this the 'wheels way'.
Do I have just one action in my controller that handles this? Or would it be best to seperate each part of the form out into separate actions?
Advise on this and possible code examples would be much appreciated.
Thanks,
Michael
The way I've done it in past is use Ajax calls and a jquery modal.
though the jquery modal is not important, I just like the aesthetic. a simple div replacement will also work.
If you cannot be sure that the users can use AJAX then it won't work for you, but you might be able to use a popup window.
The advantage of using Ajax calls for multi-step forms is that you can adjust the form content from one step to another. Another advantage is that you don't have to store user data in the cache or session. Because each time you send a form, you can use the POST or GET.
For this to work, the quickest way of setting this up is to use the plugin called RemoteFormHelpers. Then each step of the form would be a different controller (or the same one with a switch statement based on the data passed)
I think this is a pretty versatile way of doing this, but you cannot do a form that uses file-uploads, well not easily as ajax won't let you do it without some serious pain.

Django app that can provide user friendly, multiple / mass file upload functionality to other apps

I'm going to be honest: this is a question I asked on the Django-Users mailinglist last week. Since I didn't get any replies there yet, I'm reposting it on Stack Overflow in the hope that it gets more attention here.
I want to create an app that makes it easy to do user friendly,
multiple / mass file upload in your own apps. With user friendly I
mean upload like Gmail, Flickr, ... where the user can select multiple
files at once in the browse file dialog. The files are then uploaded
sequentially or in parallel and a nice overview of the selected files
is shown on the page with a progress bar next to them. A 'Cancel'
upload button is also a possible option.
All that niceness is usually solved by using a Flash object. Complete
solutions are out there for the client side, like: SWFUpload
http://swfupload.org/ , FancyUpload http://digitarald.de/project/fancyupload/
, YUI 2 Uploader http://developer.yahoo.com/yui/uploader/ and probably
many more.
Ofcourse the trick is getting those solutions integrated in your
project. Especially in a framework like Django, double so if you want
it to be reusable.
So, I have a few ideas, but I'm neither an expert on Django nor on
Flash based upload solutions. I'll share my ideas here in the hope of
getting some feedback from more knowledgeable and experienced people.
(Or even just some 'I want this too!' replies :) )
You will notice that I make a few assumptions: this is to keep the
(initial) scope of the application under control. These assumptions
are of course debatable:
All right, my idea's so far:
If you want to mass upload multiple files, you are going to have a
model to contain each file in. I.e. the model will contain one
FileField or one ImageField.
Models with multiple (but ofcourse finite) amount of FileFields/
ImageFields are not in need of easy mass uploading imho: if you have a
model with 100 FileFields you are doing something wrong :)
Examples where you would want my envisioned kind of mass upload:
An app that has just one model 'Brochure' with a file field, a
title field (dynamically created from the filename) and a date_added
field.
A photo gallery app with models 'Gallery' and 'Photo'. You pick a
Gallery to add pictures to, upload the pictures and new Photo objects
are created and foreign keys set to the chosen Gallery.
It would be nice to be able to configure or extend the app for your
favorite Flash upload solution. We can pick one of the three above as
a default, but implement the app so that people can easily add
additional implementations (kinda like Django can use multiple
databases). Let it be agnostic to any particular client side solution.
If we need to pick one to start with, maybe pick the one with the
smallest footprint? (smallest download of client side stuff)
The Flash based solutions asynchronously (and either sequentially or
in parallel) POST the files to a url. I suggest that url to be local
to our generic app (so it's the same for every app where you use our
app in). That url will go to a view provided by our generic app.
The view will do the following: create a new model instance, add the
file, OPTIONALLY DO EXTRA STUFF and save the instance.
DO EXTRA STUFF is code that the app that uses our app wants to run.
It doesn't have to provide any extra code, if the model has just a
FileField/ImageField the standard view code will do the job.
But most app will want to do extra stuff I think, like filling in
the other fields: title, date_added, foreignkeys, manytomany, ...
I have not yet thought about a mechanism for DO EXTRA STUFF. Just
wrapping the generic app view came to mind, but that is not developer
friendly, since you would have to write your own url pattern and your
own view. Then you have to tell the Flash solutions to use a new url
etc...
I think something like signals could be used here?
Forms/Admin: I'm still very sketchy on how all this could best be
integrated in the Admin or generic Django forms/widgets/...
(and this is were my lack of Django experience shows):
In the case of the Gallery/Photo app:
You could provide a mass Photo upload widget on the Gallery detail
form. But what if the Gallery instance is not saved yet? The file
upload view won't be able to set the foreignkeys on the Photo
instances. I see that the auth app, when you create a user, first asks
for username and password and only then provides you with a bigger
form to fill in emailadres, pick roles etc. We could do something like
that.
In the case of an app with just one model:
How do you provide a form in the Django admin to do your mass
upload? You can't do it with the detail form of your model, that's
just for one model instance.
There's probably dozens more questions that need to be answered before
I can even start on this app. So please tell me what you think! Give
me input! What do you like? What not? What would you do different? Is
this idea solid? Where is it not?
Thank you!
I just released a simple app for this about a month ago: django-uploadify.
It's basically a Django template tag that acts as a wrapper for the very nifty Uploadify (requires jQuery). Using it is as simple as adding this to your template...
{% load uploadify_tags }{% multi_file_upload ‘/upload/complete/url/’ %}
The tag will fire events (1 per file) on both the client-side and server-side (Django signal) to indicate when an incoming file has been received.
For example, assuming you have a model 'Media' that handles all user-uploaded files...
def upload_received_handler(sender, data, **kwargs):
if file:
new_media = Media.objects.create(
file = data,
new_upload = True,
)
new_media.save()
upload_recieved.connect(upload_received_handler, dispatch_uid=‘whatever.upload_received’)
Check out the wiki for info on how to set it up and create the signal handlers (client/server).
About your conceptual implementation from above, here's a few points of consideration:
Having the app automatically create the "File Model" instance probably isn't as robust as people may already have their own models they're working with
If you want to implement any type of security or authentication, you need an open system and less of an 'auto-create' type
I really think signals/events are the way to handle this, and also handle the 'DO OTHER STUFF' part of what you mentioned.
My conclusion was that multi-upload can never really be a form widget in the sense that Django implements form widgets. 1 file will most likely be represented by 1 model instance (with some exceptions), which means that we end up with a situation where 1 widget can represent N model instances. However Django is setup so that a widget represents 1 value for 1 field in 1 instance. It just doesn't fit for the majority of use-cases to have it as a widget (hence why I went the template tag route).