Instantiating a form in a view for a get request, why asks for 'request' argument?

When instantiating a form inside the view function e.g form = submit_bid() django crashes and gives the error " submit_bid() missing 1 required positional argument: ‘request’ ".

I’m recreating a auction site (eBay like). One of the views (view_listing) returns a template where among other things it have an input field so the user can set his own bid on the listing. The thing is that when i create the form = submit_bid() in the view to serve it to the template, i obtain the error that needs a 1 positional argument request (for what i understand i only need pass this on a POST request, and im actually working on the GET request to serve the form to the template). So django crashes. I also have another view (create_auction) where i instantiated a form succesfully (like i described before form = create_auction() and works flawesly, but in this particular view im getting problems. I will leave the code from my forms.py, also of the view. I have to mention that im new to django, and this are my first attemps to working with it

forms.py:

from django import forms
from .models import Auction, Bid, Comment, Watchlist


class create_auction(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for visible in self.visible_fields():
            visible.field.widget.attrs['class'] = 'text-center form-control mb-3'
            visible.field.widget.attrs['placeholder'] = visible.field.label
            if 'image_url' in self.fields and isinstance(self.fields['image_url'].widget, forms.Textarea): 
                self.fields['image_url'].widget.attrs['rows'] = 2
            if 'description' in self.fields and isinstance(self.fields['description'].widget, forms.Textarea):
                self.fields['description'].widget.attrs['rows'] = 2     
            

    class Meta:
        model = Auction
        # If we set the exclude fields, it will render evertything but not that ones.
        # fields = '__all__'
        exclude = ['user_owner', 'auction_on', 'date_started']
        widgets = {
            'ending_date': forms.DateInput(attrs={'type': 'date'}),
        }


class submit_bid(forms.Form):
    bid_ammount = forms.FloatField()

views.py (the particular view_listing):

def view_listing(request, id):
    form = submit_bid()
    print(form)
    if request.method == "POST" and form.is_valid:

        pass

    try:
        auction_data = get_object_or_404(Auction, id=id)
    except Http404:
        render (request, 'error_404.html')
    
    # Total number of bids on the listing
    numberof_bids_onlisting = auction_data.bids.count()
    
    # Id of the user if logged_in
    user_logged_id = request.user.id

    # A list of bids on the listing.
    bids = auction_data.bids.values_list('bid', flat=True)
    
    # The current max bid and user id of the bid.
    all_bids_on_listing = auction_data.bids.values('bid', 'user')

    max_bid_info = max(all_bids_on_listing, key=lambda x: x['bid'], default=None)


    user_bid_is_greatest = False
    if request.user.id == max_bid_info['user']:
        # Set it to true if the logged in user is the one that the bid is winning.
        user_bid_is_greatest = True
    
    return render(request, "auctions/view_listing.html", {'auction': auction_data, 'total_bids': numberof_bids_onlisting, 'max_bid_info': max_bid_info, 'user_bid_is_greatest': user_bid_is_greatest,})

Also i leave the template here (view_listing.html):

{% extends "auctions/layout.html" %}

{% block body %}
    <h2 class="view-listing-title">Listing: {{ auction.title }}</h2>
        <div class="container-fluid">
            <div class="view-listing-container container-fluid justify-content-center">
                <a href="/watchlist_add"><span class="badge text-bg-primary ">Watchlist</span></a>
                <img class="img-fluid" src="{{ auction.image_url }}">
            </div>
            <h4>{{ auction.description }}</h3>
            {% if total_bids == None %}
                <h3>${{ auction.starting_price }}</h3>
            {% else %}
                <h3>${{ max_bid_info.bid }}</h3>
            {% endif %}
            {% if request.user.is_authenticated %}
                {% if total_bids == None  %}
                    <p>There is no bid(s) still.</p>
                {% else %}
                    {% if user_bid_is_greatest %}
                        <p>{{ total_bids }} bid(s) so far. Your bid is the current bid.</p>
                    {% else %}
                        <p>{{ total_bids }}bid(s) so far.
                    {% endif %}  
                {% endif %}
                
            <form action="/submit_bid" method="POST">
                {% csrf_token %}
                {{ form.as_p }}
            </form>
            {% else %}
                {% if total_bids == None  %}
                <p>There is no bid(s) still.</p>
                {% else %}
                <p>{{ total_bids }}bid(s) so far.
                {% endif %}
            {% endif %}
            <h3>Details</h3>
            <ul>
                <li>Listed by: {{ auction.user_owner }}</li>
                <li>Category : {{ auction.auction_category }}</li>
            </ul>
        </div>
{% endblock %}

I have to say that the form its imported on the views.py, the url its registered in urls.py. If i pass the argument request to form=submit_bid(request) then when i do print(form) obtain None. I leave here the debugging image of django:

Thank you in advance guys.

Side note: I would strongly encourage you to adopt Python / Django naming conventions. It’s going to make it a lot easier for other to help you. (This means capitalizing class names - your create_auction and submit_bid forms should be named CreateAuction and SubmitBid.)

Second: It’s going to be a lot easier to diagnose this if you post the full traceback from the server’s console than the summary from the browser.

Next: is_valid is a function and not a variable - it should be form.is_valid().

Do you have any definition for something called submit_bid anywhere else in your project?

1 Like

Hi Ken, first of all, thank you for your time, really apreciate it.
Will start to use this conventions aswell! Thanks for the recomendation!
No, there is only defined on the forms.py and then imported on the view for instantiate the form.
Here is the full traceback from the console of VSCode

Internal Server Error: /view_listing/1/
Traceback (most recent call last):
  File "E:\dev\web50\jef-prg\commerce\env\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "E:\dev\web50\jef-prg\commerce\env\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "E:\dev\web50\jef-prg\commerce\auctions\views.py", line 108, in view_listing
    form = submit_bid()
           ^^^^^^^^^^^^
TypeError: submit_bid() missing 1 required positional argument: 'request'

EDIT: Now you asking for that, i think could be the problem that other view have the same name as the form? Both are “submit_bid”. My bad with the names, sorry im new i do my best hehe.

EDIT2: The problem was that the name of the form was equal to a name for another view! Thank u so much for pointing me on the right practice Ken! Apreciate it

Thank you for your help