Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
how does a html form work exactly?
#1
I have been trying to teach myself Python Django.
Been following videos on YouTube.

I'm confused in understanding how this piece of code that has been added to create a form, works exactly.
Before I explain, I would like to point out that my model for the Song class has a Boolean field called is_favourite with the default set to False.

Here is the code for the form:

<form action="{% url 'music:favourite' album.id %}" method="post">
  {% csrf_token %}
  {% for song in album.song_set.all %}
      <input type="radio" id="song{{ forloop.counter }}" name="song" value="{{ song.id }}">
      <label for="song{{ forloop.counter }}">
          {{ song.song_title }}
          {% if song.is_favourite %}
              <img src="{% static 'music/images/star.jpg' %}" width="20" height="20">
          {% endif %}
      </label><br>
  {% endfor %}
  <input type="submit" value="Favourite">
</form>
I have attached an image of what the form looks like when I run the development server (it is boxed in red).
The purpose of the form is to allow users to "favourite" their songs.
When they have favourited their song(s), they click on the "Favourite" button which I believe submits all of the form data to the url 'music:favourite' which calls views.favourite function:

def favourite(request, album_id):
    album = get_object_or_404(Album, pk=album_id)
    selected_song = album.song_set.get(pk=int(request.POST['song']))
    if selected_song.is_favourite:
        selected_song.is_favourite = False
    else:
        selected_song.is_favourite = True
    selected_song.save()
    return render(request, 'music/detail.html', {'album':album})
I understand that the code in the form runs before the associated function in the view is called. Having said that, it is this line in the form code that I can't get my head around in understanding how it works:

{% if song.is_favourite %}
    <img src="{% static 'music/images/star.jpg' %}" width="20" height="20">
{% endif %}
I understand this is saying if the field "is_favourite" of the Song class is set to True, then add a little star image next to that song. But all songs are set to False when you try to run the form for the first time. So that line of code does not get executed i.e. a star image is not added to any of the songs. But let's say a user selects a song as a favourite and then clicks the submit button, does it only send that particular song the to the function in the view? If so, how does it know to only send that song, is this something to do with the mechanics of how "radio" button in html forms operates or am I missing something? Aside from this question, if the function then sets the field value of "is_favourite" of that particular song to True, then how does the "star" icon get added in the first place? We have already executed the lines of code in the form code and then we went to the view function which set the property to True so unless a call is made back to the code in the form to set the star icon, I don't quite understand.

Thank You in advance.

Attached Files

Thumbnail(s)
       
Reply
#2
When you render the page and load the form for the first time is_favorite for all songs is False.
In the given example album has four songs. There is one radio control for each song. They have different ids and different value (the id of the song) but the same name ('song').
When you submit the form you post one key-value pair - {'song':song.id} where song.id is the respective id of the song (the value of the selected radio control).

Now your python function

    selected_song = album.song_set.get(pk=int(request.POST['song']))
    if selected_song.is_favourite:
        selected_song.is_favourite = False
    else:
        selected_song.is_favourite = True
    selected_song.save()
here it basically toggle the is_favourite property of the song - if it was True it will become False and vice-verse. This is important later on, because this is how you will in-favorite song that was previously favorite.

at the end of the python function you render the same page, however now the album that you pass has changed and one song is favorite. That is why the respective lines you identified correctly will execute and show a star next to the song. If you now submit the form with the same song selected, it will in-favorite it and next time page is rendered it will not display star next to it.

as a side note that
if selected_song.is_favourite:
    selected_song.is_favourite = False
else:
    selected_song.is_favourite = True
can be replaced with just
selected_song.is_favourite = not selected_song.is_favourite
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
thank you for the explanation.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Post HTML Form Data to API Endpoints Dexty 0 1,382 Nov-11-2021, 10:51 PM
Last Post: Dexty
  HTML multi select HTML listbox with Flask/Python rfeyer 0 4,536 Mar-14-2021, 12:23 PM
Last Post: rfeyer
  Using Python request without selenium on html form with javascript onclick submit but eraosa 0 3,135 Jan-09-2021, 06:08 PM
Last Post: eraosa
  Using python within an html form t4keheart 5 5,236 Aug-17-2020, 12:28 PM
Last Post: t4keheart
  Python3 + BeautifulSoup4 + lxml (HTML -> CSV) - How to loop to next HTML/new CSV Row BrandonKastning 0 2,329 Mar-22-2020, 06:10 AM
Last Post: BrandonKastning
  requests post/get to HTML form mrdominikku 1 2,300 Nov-03-2019, 07:12 PM
Last Post: Larz60+
  getting options from a html form pgoosen 5 3,195 Jul-03-2019, 06:07 PM
Last Post: nilamo
  How to send data from remotely hosted HTML form to Pi sajid 2 2,533 Jun-27-2019, 10:28 PM
Last Post: sajid
  how i save the html form to flask database mebaysan 1 7,246 Feb-07-2019, 12:56 AM
Last Post: snippsat
  Python....excel....html form tarliver 2 7,304 Dec-20-2017, 07:02 AM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020