简体   繁体   中英

How can I create a submit form in Django with a dropping down list?

I am just starting to work with Django and I have some problems with forms and dropping lists.

I have a model with two attributes, and I want to display one of the attributes in a dropping down list (this one will be unchangeable) and another one in a text field (this one will be changeable). Also, I have a submit button, so I want to change a second attribute in a text field and by pressing on the button. How can I do this? What would some examples be?

As you are starting to work with Django, you might or might not know about how Django handle forms.

In Django, forms can be handled in two ways:

  1. User-created and managed forms (without any form class)
  2. Class-managed forms (connected to Django models)

Documentation form Django Forms

Now let's talk about the first type of forms (where you create your HTML form and manage the request sent to server):

These forms are simple to make and when there are only a few and are only suggested when you have a very small amount of inputs (I would say four or fewer inputs ).

Here is a simple example of subscription of a newsletter with an email example.

<form id='sub-form' method="POST">
    {% csrf_token %}
    <div>
         <input type="email" name="sub_email">
    </div>
    <input class="button" value="Subscribe" type="submit" id="subbutton">
</form>

So a very important thing to look at here is {% csrf_token %} , about which you can read more about here and about how it works and prevents cross-site request forgery . This token will be required when you make a request to Django server with any post request and data.

In this subscription form you see one <input> with name="sub_email" . Take note of this as we will use this to get this value on the server as this is the key to its value , and then a simple Submit Button .

When you press Submit on a page let's say url = " http://BASE_URL/home" you will receive a POST request on the view that handles that URL.

So now coming to the view.py , let's say you only allow registered users to subscribe then the view will go something like this (assuming you are not expecting any other request from the home URL).

def home(request):
    user=request.user
    if request.method == "POST":
        if user.is_authenticated:
            email = request.POST['sub_email'] #Using name of input
            #Logic to save this email
            return HttpResponse("You are Subscribed",status=200)
        else:
            return HttpReposnse("You are not Authenticated",status=401)
    else:
        return render(request,"home.html")

Now as you are the expert of simple forms, let's work with Django class-based forms.


These views are a little work when you have very few inputs, but they are a great help in manageability and when you have to work with large number of inputs.

You will request these Class Based Forms as in your question you are trying to send an instance of a model from your Models.py to a form to user.

I have a model of Posts that can be used for this example:

class Post(models.Model):
    postTitle = models.CharField(max_length = 90,null=True)
    subTitle = models.CharField(max_length = 160,null=True)
    location = models.CharField(max_length = 3,default = 'IN',null=True)

Now according to your question, you are trying to let the user change one attribute, let's say postTitle and for location you are not letting the user select one of the countries which is preselected and for your post.

Now we have to create a form for this. Forms in class based are created in Forms.py . If you don't have forms.py then you can create one right along models.py and views.py .

表单.py

Now for the form, I would like to edit some existing data as you are saying one of the attributes (Fields) is fixed and another editable, but you get the value from the model.

class PostEditForm(ModelForm):
    location = forms.CharField(label='Country ',widget=forms.Select(attrs={'class': 'Classes_HERE','placeholder':' Select a Country','disabled':'disabled'} ,choices=country_list),required=True)

    class Meta:
        model = Post
        fields= ['postTitle','subTitle','location']
        labels = {
            'postTitle':'Title',
            'subTitle':'Sub-Title',
        }
        widgets = {
            'postTitle': forms.TextInput(attrs={'class': 'mention_class_here','placeholder':' Add Title'}),
            'subTitle': forms.TextInput(attrs={'class': 'mention_class_here','placeholder':' Add Sub-Title'})
        }

Attributes can be mentioned in forms fields the way I have mentioned them in the above example. I used disabled="disabled" to disable ( not editable ) location field and used forms.Select to make it drop down.

You might also see that I gave the location field a list to choose from. This is how you can create a list of your items. It's been quite some time when I wrote this, so there might be errors or it may not work for you, so just make sure you are referring to the current documentation and searching Stack Overflow for answers.

country_list = [
    ('', 'Select a Country'),
    ("AF", "Afghanistan"),
    ("AX", "Aland Islands"),
    ("AL", "Albania"),
    ("DZ", "Algeria"),
    ("AS", "American Samoa"),
    ("AD", "Andorra"),
    ("AO", "Angola"),
    ("AI", "Anguilla"),
    ("AQ", "Antarctica"),
    ("AG", "Antigua And Barbuda"),
    ("AR", "Argentina"),
    ("AM", "Armenia"),
    ("AW", "Aruba"),
.
.
.

Now this form can be passed as context in a view to an HTML page.

def editPost(request,post_id):
    user=request.user
    post = get_object_or_404(Post,id=post_id) #Getting the instance of Post
    if user.is_authenticated:
        formPost = PostEditForm(request.POST or None,instance=post)

        if request.method=='POST':
            if formPost.is_valid():
                    savedPost=formPost.save()
        else:
            return render(request,'postEdit.html',{'formPost':formPost})
    else:
        return HttpResponse("Not Authorized",status:401)

Now your HTML file postEdit.html should look something like this:

<form id="post-form" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <div>
        {{formPost}}
    </div>
</form>

That is it and adding a submit button in the same form, you can now edit your instance of post that you passed along with this {{formPost}} . Combine your logic wherever you think needs a change to fit in what you want to do.

By no means I am saying all this code is in working condition, but it is shown only to illustrate the flow and working.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM