Django Tutorial - Custom Forms

# Creating Custom Dynamic Forms in Django: A Step-by-Step Tutorial

In this tutorial, we will guide you through the process of creating custom dynamic forms in Django. This builds on our previous video where we worked with basic Django forms using form classes. Today, we aim to make your forms more interactive and user-friendly by allowing users to add items to their todo list and track whether they are complete or incomplete.

---

## Introduction

The goal of this tutorial is to enable users to perform two key tasks:

1. **Add new items** to their todo list.

2. **Mark items as complete/incomplete** using checkboxes.

Currently, our application only allows users to create new todo lists but lacks functionality for adding individual items or tracking completion status. We will address these gaps by creating a custom form that handles both tasks dynamically.

---

## Setting Up the Form in HTML

To achieve this, we need to set up a form within our HTML file. The form must handle POST requests to send data back to our view. Here's how we structure the form:

```html

{% for item in todo_list %}

  • name="c{{item.id}}"

    {% if item.complete %}checked{% endif %}>

    {{item.text}}

  • {% endfor %}

    {% csrf_token %}

    ```

    ### Explanation:

    1. **Form Structure**: The form uses the `post` method to send data securely.

    2. **Buttons**: We include two buttons:

    - **Save**: Updates the completion status of items.

    - **Add Item**: Adds new items to the todo list.

    3. **Input Field**: A text field (`name="new"`) allows users to input new todo items.

    4. **Checkboxes**: Each todo item has a checkbox. The `name` attribute is set to `c{{item.id}}`, where `{{item.id}}` is replaced with the actual item ID during rendering. This helps us identify which checkboxes are checked when the form is submitted.

    ---

    ## Handling Form Data in Django Views

    Once the form is set up, we need to handle the data it sends to our view. Here's how we process the form submission:

    ```python

    def index(request):

    if request.method == 'POST':

    # Process checkbox updates

    if request.POST.get('save'):

    for item in TodoItem.objects.all():

    checkbox_name = f'c{item.id}'

    if request.POST.get(checkbox_name) == 'clicked':

    item.complete = True

    else:

    item.complete = False

    item.save()

    # Process new item addition

    elif request.POST.get('add_item'):

    text = request.POST.get('new')

    if len(text) > 2:

    TodoItem.objects.create(text=text, complete=False)

    return render(request, 'index.html', {'todo_list': TodoItem.objects.all()})

    ```

    ### Explanation:

    1. **Save Button Handling**:

    - When the Save button is clicked, we loop through all todo items.

    - For each item, we check if its corresponding checkbox was marked using `request.POST.get()`.

    - If checked, we set `item.complete = True`; otherwise, `item.complete = False`.

    2. **Add Item Handling**:

    - When the Add Item button is clicked, we retrieve the input value from the `new` field.

    - We validate the input to ensure it has at least 3 characters.

    - If valid, we create a new `TodoItem` with the provided text and set `complete=False`.

    ---

    ## Testing the Form

    After implementing these changes, you can test the functionality:

    1. **Adding Items**: Type a new item in the input field and click "Add Item."

    2. **Checking/Unchecking Items**: Click the checkbox next to an item to mark it as complete or incomplete.

    3. **Saving Changes**: Click the "Save" button to persist any changes you've made to the checkboxes.

    ---

    ## Conclusion

    By following this tutorial, you have successfully created a custom dynamic form in Django that allows users to add new items and track their completion status. This approach provides a solid foundation for building more complex forms and interactive features in your Django applications.

    In our next video, we will explore how to enhance the user interface by adding Bootstrap styling and additional features like a sidebar. Stay tuned!

    "WEBVTTKind: captionsLanguage: enhey guys and welcome back to another django tutorial so in today's video we're gonna be going a bit more advanced with forums be showing you how to create your own custom forms that are a bit more dynamic than typical django forms that we were using in the last video using that forms class and whatnot so yeah I guess let's get into it so the goal today kind of is to allow the user to add an item from their to-do list so right now we don't actually have any way for them to add items we only have ways for them to add new to-do lists so we're gonna do that we're also gonna add some check buttons beside the to-do list items so we can show whether or not they are complete or incomplete without having to do this in complete complete kind of thing so right off the bat I'm actually just gonna delete this incomplete and complete for now and I'm gonna start setting up a form inside of my HTML file here now the reason we need a form is because we need to pass the information like whether the user click the check button or whether they what item for example they typed in to add to the list we need to pass that back to our view using a post request so we need a form to do that so I'm going to start by creating a form I'm going to say method equals and in this case post and I'm going to say action what he call it equals pound like this okay we're number son whatever you want to call it now I will simply close my form by doing that and now I'm going to start by just setting up some buttons at the bottom of my form that say save and that say add item so what I'm gonna have is I'm gonna have two buttons save add item save is gonna save you the changes to your checks and add item is gonna add item that we will get from a text field that I'm also gonna add so the first button that I would create will be that Save button so to do that I'm just gonna say button I will say type equals and in this case what do we need type for a button yeah we do will say type equals submit we'll say name equals and in this case but it'll just be saved and I'll say value equals and I can say save it here as well now when I close my button I'll put whatever I want to display on it here so in this case I'm gonna say save and I'll copy this actually and I'm gonna just use the same thing except instead of name I'm gonna say new item I don't know why at that tabbed there and will give that value of new item as well and obviously now I'm just gonna make this add item I mean I could make a new item too it doesn't really matter and even between here I'm going to add an input field which is my text that you're gonna type in for when you create a new button so I'm gonna say input will say type equals text and we'll say name equals I so could say item why not I know stroyed not the best name actually let's just say new alright news probably not a good name either but whatever that's fine okay so type equals text name equals new and sweet now what I'm gonna do now is add those check buttons in beside all of our items so obviously if our item is complete we want that check button to start off as checked and if it's not we want it to not be checked so to do this it's similar to the text we're just gonna say input I'm gonna say type equals and in this case checkbox will say value equals clicked and you can call this whatever you want but just remember this name because we're gonna need to use this I'm gonna say name is equal to and this is a little bit weird but we're gonna set the name equal to the ID of our item so to do this what I'm gonna do is just go in here and say item dot ID and before that I'm gonna put a C so that what we're gonna do now is we're gonna say all of our check buttons because this is gonna create a bunch of different check buttons right they're gonna be given the name C and then whatever the ID of that button is this will just make it way easier for us to determine which check button was checked and what item that corresponds to and you'll see how we do that later so let's copy this now and I'm going to put it right here as well so inside these Li tags now the only difference is up here where it says is completely if item dot complete equals true I'm just gonna type checked like this which will default it to start off checked that's all that's gonna do for us okay so now we've actually set up this form the last thing to add is our CSRF token that we always need to add whenever we create a token or a forms are so CSRF underscore token like that and then hit save so now that we've done that our HTML will be showing up all night and now we just need to handle this from our view so remember our view is called index so what I want to do in here now very similar to create is I want to first off start by checking whether or not we have posted something or we're getting something so for posting something we're gonna say if and then this case response dot post or not post Seraph dot method equals equals post like that then we will start doing all the stuff in terms of saving and adding items now I want to quickly go back here and talk about something for a second so right now we have two buttons we have save and we have new item and these buttons might have different functions and they do in this instance so for example save well we only want save to look at and update the check buttons right that's what it's gonna do it's just gonna update your check buttons if you've completed an item or if you haven't completed it whereas our new item button or add item button is going to take the text from this text field and add it as a new item on our list so we need a way to determine which button we clicked so we can determine what function we're going to perform so to do this what you can do actually is gonna say if response dot post dot gets and then here you can put the name of your button so in this case I'm gonna say we'll start off by doing save save like this okay now what this does actually is whenever you get a post request from the server what's gonna happen is all the information in this form here is gonna be passed in what's known as a dictionary to our view so what's gonna happen is we're gonna get a dictionary that looks something like this so we'll have save and it will either have no value or it will have a value of whatever we typed ears value so for example save if we click this button what's gonna happen is it's gonna be added to a dictionary which is all of the information from this form and it's gonna be given this value only if we click it so what's gonna happen is we're gonna get the name save points to the value save and it's gonna look like this precisely okay we're also gonna get all of the information for our check buttons so what will happen is we'll get something like C 1 which will be that ID right C 1 and that'll point to you in here it'll say and I'll print this out after you so you guys can have a look at it it'll say clicked if we clicked the check button if we didn't click the check button we're just gonna get a blank string or c1 might not even show up in the dictionary okay so and then we can also try what do you call it for example like add item we can do the same thing with add item now the thing is if we click add item then it will come in and it will give the value of add item otherwise it won't give us any value just give us a blank string and you guys will see how this works in a second I'm gonna print it out for you so you can have a look so let's actually if we are posting let's print response dot post like that so you guys can have a look okay so anyways so we're gonna see if we are saving so if we're saving then this will evaluate to true because there'll be some value so that will just work otherwise we'll say what do you call it Elif response dot post and dot get and in this case instead of saying say if we're gonna say new I think was a new item I keep forgetting what I call this yes new item awesome new item okay so we'll just pass down here for now and let's work inside of this first one up here so what we want to do up here is we want to look at all the different check buttons and determine whether or not they were clicked or not and then update our item accordingly so to do this what I'm gonna do is I'm going to loop through all of the items in our current to-do list because we still have this value up here and we're gonna check the IDS of that with the check buttons and see if it was clicked or not so to do this I'm gonna say for I guess we'll say item in in this case LS dot item underscore set dot all with lowercase LS okay then what we will do is we'll say if and in this case response dot post dot get and in here what we're going to do is we're going to say c plus str and then item dot ID now what this is doing is getting the item ID converting it to a string and adding ascii to the beginning of it so we will get the exact same kind of pattern of what do you call it names or ids as we were setting up here right so we have seen that item ID that's just what we're doing here so if we get that and that is equal to the you have clicked then what we need to do is well we need to update that item so we'll say item dot complete is equal to and in this case true now otherwise so if we didn't get that it wasn't equal to clicked we'll take this but we're gonna set it equal to false so this is the same as like if you unclick the check button and it doesn't it's not checkmark then this will run right here what I'm doing now and then all we can simply do down here and just say is actually inside the for-loop will say item dot save and there we are sweet so that's how that works and that's actually it for this saving the check buttons now what's left to do is to add a new item this is it's similar in terms of how we knew this but we're going to start by doing is getting the text that was in that text input field here so the name was new so say text is equal to and in this case response dot post dog yet and here we're saying new and now what I'm gonna do is before I add this new item because this will give us the text I want to validate that this is valid input now you can do whatever checks you want on this input and usually Django will do it for you but since we're not using Django forms using our own custom form we don't have that option of using is valid like we used here so what I'm gonna do is just say if text now you select you say the Len of text is greater than two so it's at least three characters then I will simply add that item to the to-do list so to do that I'm gonna say LS dot item underscore set dark create and in this case we'll say text equals and I'm actually gonna have to rename this to txt here I will say txt and then we will say complete equals false like so otherwise I'm just gonna print out a message it just says like invalid input just so that we can have a look at this in the console and that should actually be about it now I'd be surprised if I didn't make any mistakes but let's give this a run I already have the server actually I'm gonna have to run the server again here run the server so let's now attempt to go to like ID two so now we can see we have first item second item third item not showing now if I decide to check an item or uncheck hit save what is your issue here name respond uh well it would help if I spell to response correctly where did i misspelled that recourse in the print statement anyways let's see if this will update now python managed up hi run server did i make another mistake let's see - okay now let's try it safe there we go so then you can see that the item saves now if I go to maybe let's say page three and I want to add an item let's try hello and we click add item and now you can see that we get hello popping up and I can check I can save that I can unsaved it and if I go back to two you can see that obviously the same checking pattern is still there I could add a new item so let us say new item here add that and you can see that it's popping up and I can save that so that is how you make a custom form this is very useful what I've just shown you will allow you to do pretty well anything with forms because now you know how to get information from forms now I will show you actually what our post requests are looking like just so you can see or sorry was it requests like what I'm printing here I'll show you what that looks like and talked a little bit about that before we wrap up here so you can see that if I go here we have check button see - and that is given a value of clicked you can see C 5 is given a value clicked and C 7 is given a value clicked so those IDs for our check buttons we see that save is given the value of save because we hit that Save button but we see that we're not seeing any other values here right so if we don't click an item or if we're not giving a value to it we're not gonna see it here so for example like if we have C 2 and we don't check that button you're just simply not gonna show up in the information that it passed to us which means that we can check if it's not there and then do something accordingly so the way that this get request works when we say get like this or this gap method is since this is it's like this is kind of a dictionary but this gap method is specific to this type of data structure and essentially if the item doesn't exist I believe it just returns none which means that if we ever put something like this so for example if save isn't there we simply won't run the block because if none obviously it's not gonna run so that's the way that that kind of works you can see I mean I brewed highly encourage you guys to kind of mess with this and do some requests print them out and see what it looks like that's really the best way to understand how this works you can see it's a type query dictionary and when you try to get something if it doesn't exist it just says none if it does exist it'll give you the value that corresponds with it and in some instances you can actually have multiple values pointing to the same name so that's just something to keep in mind that you guys might notice when you go through this so anyways that is essentially how that works we've create a custom form now we know to add things and with this information we can go into creating some more complex stuff so in the next video I think I'm gonna be adding bootstrap onto the website making things look a little bit nicer maybe adding a sidebar will do some stuff like that and then later on we're gonna get into user registration and all that kind of stuff so that you can actually have all of your to-do lists stored under a certain user so anyway so that has been it for this video if you guys enjoyed please make sure you leave a like and subscribe and I'll see you in another videohey guys and welcome back to another django tutorial so in today's video we're gonna be going a bit more advanced with forums be showing you how to create your own custom forms that are a bit more dynamic than typical django forms that we were using in the last video using that forms class and whatnot so yeah I guess let's get into it so the goal today kind of is to allow the user to add an item from their to-do list so right now we don't actually have any way for them to add items we only have ways for them to add new to-do lists so we're gonna do that we're also gonna add some check buttons beside the to-do list items so we can show whether or not they are complete or incomplete without having to do this in complete complete kind of thing so right off the bat I'm actually just gonna delete this incomplete and complete for now and I'm gonna start setting up a form inside of my HTML file here now the reason we need a form is because we need to pass the information like whether the user click the check button or whether they what item for example they typed in to add to the list we need to pass that back to our view using a post request so we need a form to do that so I'm going to start by creating a form I'm going to say method equals and in this case post and I'm going to say action what he call it equals pound like this okay we're number son whatever you want to call it now I will simply close my form by doing that and now I'm going to start by just setting up some buttons at the bottom of my form that say save and that say add item so what I'm gonna have is I'm gonna have two buttons save add item save is gonna save you the changes to your checks and add item is gonna add item that we will get from a text field that I'm also gonna add so the first button that I would create will be that Save button so to do that I'm just gonna say button I will say type equals and in this case what do we need type for a button yeah we do will say type equals submit we'll say name equals and in this case but it'll just be saved and I'll say value equals and I can say save it here as well now when I close my button I'll put whatever I want to display on it here so in this case I'm gonna say save and I'll copy this actually and I'm gonna just use the same thing except instead of name I'm gonna say new item I don't know why at that tabbed there and will give that value of new item as well and obviously now I'm just gonna make this add item I mean I could make a new item too it doesn't really matter and even between here I'm going to add an input field which is my text that you're gonna type in for when you create a new button so I'm gonna say input will say type equals text and we'll say name equals I so could say item why not I know stroyed not the best name actually let's just say new alright news probably not a good name either but whatever that's fine okay so type equals text name equals new and sweet now what I'm gonna do now is add those check buttons in beside all of our items so obviously if our item is complete we want that check button to start off as checked and if it's not we want it to not be checked so to do this it's similar to the text we're just gonna say input I'm gonna say type equals and in this case checkbox will say value equals clicked and you can call this whatever you want but just remember this name because we're gonna need to use this I'm gonna say name is equal to and this is a little bit weird but we're gonna set the name equal to the ID of our item so to do this what I'm gonna do is just go in here and say item dot ID and before that I'm gonna put a C so that what we're gonna do now is we're gonna say all of our check buttons because this is gonna create a bunch of different check buttons right they're gonna be given the name C and then whatever the ID of that button is this will just make it way easier for us to determine which check button was checked and what item that corresponds to and you'll see how we do that later so let's copy this now and I'm going to put it right here as well so inside these Li tags now the only difference is up here where it says is completely if item dot complete equals true I'm just gonna type checked like this which will default it to start off checked that's all that's gonna do for us okay so now we've actually set up this form the last thing to add is our CSRF token that we always need to add whenever we create a token or a forms are so CSRF underscore token like that and then hit save so now that we've done that our HTML will be showing up all night and now we just need to handle this from our view so remember our view is called index so what I want to do in here now very similar to create is I want to first off start by checking whether or not we have posted something or we're getting something so for posting something we're gonna say if and then this case response dot post or not post Seraph dot method equals equals post like that then we will start doing all the stuff in terms of saving and adding items now I want to quickly go back here and talk about something for a second so right now we have two buttons we have save and we have new item and these buttons might have different functions and they do in this instance so for example save well we only want save to look at and update the check buttons right that's what it's gonna do it's just gonna update your check buttons if you've completed an item or if you haven't completed it whereas our new item button or add item button is going to take the text from this text field and add it as a new item on our list so we need a way to determine which button we clicked so we can determine what function we're going to perform so to do this what you can do actually is gonna say if response dot post dot gets and then here you can put the name of your button so in this case I'm gonna say we'll start off by doing save save like this okay now what this does actually is whenever you get a post request from the server what's gonna happen is all the information in this form here is gonna be passed in what's known as a dictionary to our view so what's gonna happen is we're gonna get a dictionary that looks something like this so we'll have save and it will either have no value or it will have a value of whatever we typed ears value so for example save if we click this button what's gonna happen is it's gonna be added to a dictionary which is all of the information from this form and it's gonna be given this value only if we click it so what's gonna happen is we're gonna get the name save points to the value save and it's gonna look like this precisely okay we're also gonna get all of the information for our check buttons so what will happen is we'll get something like C 1 which will be that ID right C 1 and that'll point to you in here it'll say and I'll print this out after you so you guys can have a look at it it'll say clicked if we clicked the check button if we didn't click the check button we're just gonna get a blank string or c1 might not even show up in the dictionary okay so and then we can also try what do you call it for example like add item we can do the same thing with add item now the thing is if we click add item then it will come in and it will give the value of add item otherwise it won't give us any value just give us a blank string and you guys will see how this works in a second I'm gonna print it out for you so you can have a look so let's actually if we are posting let's print response dot post like that so you guys can have a look okay so anyways so we're gonna see if we are saving so if we're saving then this will evaluate to true because there'll be some value so that will just work otherwise we'll say what do you call it Elif response dot post and dot get and in this case instead of saying say if we're gonna say new I think was a new item I keep forgetting what I call this yes new item awesome new item okay so we'll just pass down here for now and let's work inside of this first one up here so what we want to do up here is we want to look at all the different check buttons and determine whether or not they were clicked or not and then update our item accordingly so to do this what I'm gonna do is I'm going to loop through all of the items in our current to-do list because we still have this value up here and we're gonna check the IDS of that with the check buttons and see if it was clicked or not so to do this I'm gonna say for I guess we'll say item in in this case LS dot item underscore set dot all with lowercase LS okay then what we will do is we'll say if and in this case response dot post dot get and in here what we're going to do is we're going to say c plus str and then item dot ID now what this is doing is getting the item ID converting it to a string and adding ascii to the beginning of it so we will get the exact same kind of pattern of what do you call it names or ids as we were setting up here right so we have seen that item ID that's just what we're doing here so if we get that and that is equal to the you have clicked then what we need to do is well we need to update that item so we'll say item dot complete is equal to and in this case true now otherwise so if we didn't get that it wasn't equal to clicked we'll take this but we're gonna set it equal to false so this is the same as like if you unclick the check button and it doesn't it's not checkmark then this will run right here what I'm doing now and then all we can simply do down here and just say is actually inside the for-loop will say item dot save and there we are sweet so that's how that works and that's actually it for this saving the check buttons now what's left to do is to add a new item this is it's similar in terms of how we knew this but we're going to start by doing is getting the text that was in that text input field here so the name was new so say text is equal to and in this case response dot post dog yet and here we're saying new and now what I'm gonna do is before I add this new item because this will give us the text I want to validate that this is valid input now you can do whatever checks you want on this input and usually Django will do it for you but since we're not using Django forms using our own custom form we don't have that option of using is valid like we used here so what I'm gonna do is just say if text now you select you say the Len of text is greater than two so it's at least three characters then I will simply add that item to the to-do list so to do that I'm gonna say LS dot item underscore set dark create and in this case we'll say text equals and I'm actually gonna have to rename this to txt here I will say txt and then we will say complete equals false like so otherwise I'm just gonna print out a message it just says like invalid input just so that we can have a look at this in the console and that should actually be about it now I'd be surprised if I didn't make any mistakes but let's give this a run I already have the server actually I'm gonna have to run the server again here run the server so let's now attempt to go to like ID two so now we can see we have first item second item third item not showing now if I decide to check an item or uncheck hit save what is your issue here name respond uh well it would help if I spell to response correctly where did i misspelled that recourse in the print statement anyways let's see if this will update now python managed up hi run server did i make another mistake let's see - okay now let's try it safe there we go so then you can see that the item saves now if I go to maybe let's say page three and I want to add an item let's try hello and we click add item and now you can see that we get hello popping up and I can check I can save that I can unsaved it and if I go back to two you can see that obviously the same checking pattern is still there I could add a new item so let us say new item here add that and you can see that it's popping up and I can save that so that is how you make a custom form this is very useful what I've just shown you will allow you to do pretty well anything with forms because now you know how to get information from forms now I will show you actually what our post requests are looking like just so you can see or sorry was it requests like what I'm printing here I'll show you what that looks like and talked a little bit about that before we wrap up here so you can see that if I go here we have check button see - and that is given a value of clicked you can see C 5 is given a value clicked and C 7 is given a value clicked so those IDs for our check buttons we see that save is given the value of save because we hit that Save button but we see that we're not seeing any other values here right so if we don't click an item or if we're not giving a value to it we're not gonna see it here so for example like if we have C 2 and we don't check that button you're just simply not gonna show up in the information that it passed to us which means that we can check if it's not there and then do something accordingly so the way that this get request works when we say get like this or this gap method is since this is it's like this is kind of a dictionary but this gap method is specific to this type of data structure and essentially if the item doesn't exist I believe it just returns none which means that if we ever put something like this so for example if save isn't there we simply won't run the block because if none obviously it's not gonna run so that's the way that that kind of works you can see I mean I brewed highly encourage you guys to kind of mess with this and do some requests print them out and see what it looks like that's really the best way to understand how this works you can see it's a type query dictionary and when you try to get something if it doesn't exist it just says none if it does exist it'll give you the value that corresponds with it and in some instances you can actually have multiple values pointing to the same name so that's just something to keep in mind that you guys might notice when you go through this so anyways that is essentially how that works we've create a custom form now we know to add things and with this information we can go into creating some more complex stuff so in the next video I think I'm gonna be adding bootstrap onto the website making things look a little bit nicer maybe adding a sidebar will do some stuff like that and then later on we're gonna get into user registration and all that kind of stuff so that you can actually have all of your to-do lists stored under a certain user so anyway so that has been it for this video if you guys enjoyed please make sure you leave a like and subscribe and I'll see you in another video\n"