Passing a Value to Different View and Pre-selecting it From a Drop Down List

I’m wanting to make it so when I click my apply now button it redirects to my application page and it pre-selects the property from a drop-down list. What is the best and most optimal way to accomplish this action? I’ve tried adding the property ID to the session but I wasn’t able to pre-select the property from the drop-down box.


My form

class ApplicationForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ApplicationForm, self).__init__(*args, **kwargs)
        self.fields['property'].queryset = Property.objects.filter(is_active=True)

    class Meta:
        model = Application
        fields = '__all__'
        exclude = {
            'application_date'
        }
        widgets = {
            'requested_move_in_date': DateInput(),
        }
        labels = {
            'requested_move_in_date': 'Requested Move-in Date'
        }

Property Detail View

class PropertyDetailView(DetailView):
    model = Property

    def get_context_data(self, **kwargs):
        context = super(PropertyDetailView, self).get_context_data(**kwargs)
        self.request.session['property_ID'] = self.object.pk
        return context

Application View (GET method)

    else:
        person_form = PersonForm(prefix='person')
        current_address_form = AddressForm(prefix='current_address')
        previous_address_form = AddressForm(prefix='previous_address')
        employment_form = EmploymentForm(prefix='employment')
        application_form = ApplicationForm(prefix='application')
        if "property_ID" in request.session:
            propertyid = request.session.get("property_ID")
            print(propertyid)
            #application_form.fields
            del request.session["property_ID"]


    return render(request, 'base/application.html', {'person': person_form,
                                                     'current_address': current_address_form,
                                                     'previous_address': previous_address_form,
                                                     'employment': employment_form,
                                                     'application': application_form
                                                      })

The JavaScript for handling that button needs to read the value of the selected element from the drop-down, and pass that into the request. (It can be done as part of the URL, a query variable, or - not really recommended - as post data.)

Or, if there’s a separate “Apply Now” button being generated for each property, you could build the URL in Django as the template is being rendered.

I think you have it backwards. I’m passing the value to the view with the drop-down box.

Each property has its own Apply Now button. This is how I want to do it. I’ve just never done this before and my google-fu isn’t pulling up the results or documentation I’m looking for.

Here is my code for my buttons

                <div class="container-fluid">
                    <a class="btn btn-primary" href="{% url 'base:property_edit' slug=property.slug %}">Edit</a>
                    <a class="btn btn-danger" href="{% url 'base:property_delete' slug=property.slug %}">Delete</a>
                    <a class="btn btn-primary" href="{% url 'base:application' %}" id="apply_now">Apply Now!</a>
                </div>

And my URLS

    path('', views.HomeView.as_view(), name='home'),
    path('application/', views.Application_View, name='application'),
    path('coapplication/', views.CoApplication_View, name='coapplication'),
    path('applications_list/', views.ApplicationListView.as_view(), name="application_list"),
    path('applications_list/<int:pk>/', views.Application_Details, name="application_detail"),
    path('applications_list/<int:pk>/delete', views.ApplicationDeleteView.as_view(), name="application_delete"),


    path('properties/', views.PropertiesListView.as_view(), name='properties'),
    path('new_property/', views.AddPropertyView.as_view(), name='new_property'),
    path('properties/<slug:slug>/', views.PropertyDetailView.as_view(), name='property_details'),
    path('properties/<slug:slug>/delete/', views.PropertiesDeleteView.as_view(), name='property_delete'),
    path('properties/<slug:slug>/edit/', views.PropertiesUpdateView.as_view(), name='property_edit'),

Yep, that I did. I couldn’t tell from the two images if that was one page or two.

So you can change your URL to accept a parameter in much the same way that the other buttons do, where that parameter is a unique identifier for the property.

You can then have this URL accept a parameter, (Or you can add another URL with a parameter if you still need a URL that doesn’t have one.)

Your application view can then accept the (optional) parameter to select the instance of the property to use to prepopulate the form.

I got the part about adding a parameter

<a class="btn btn-primary" href="{% url 'base:application_withID' pk=property.id %}" id="apply_now">Apply Now!</a>

For my URLs, I do need to keep the URL for accessing the application because it’s used else where. This is something I haven’t had to do yet.

    path('application/', views.Application_View, name='application'),
    path('application/<int:pk>/', views.Application_View, name='application_withID'),

When I do this I get this error. Do I need a different view for the kwarg?

TypeError at /application/4/
Application_View() got an unexpected keyword argument 'pk'
Request Method:	GET
Request URL:	http://127.0.0.1:8000/application/4/
Django Version:	4.0
Exception Type:	TypeError
Exception Value:	
Application_View() got an unexpected keyword argument 'pk'

You do not need a different view. You just need to allow for that parameter to be (optionally) supplied.

Review: Writing your first Django app, part 3 | Django documentation | Django
Then see: URL dispatcher | Django documentation | Django

I think I got it. Now the final part is how do I use that parameter to select a default value from the drop-down list?

Edit:
I got this to work. If there is a better way or a correct way please let me know.

def Application_View(request, pk=None):
    if request.method == 'POST':
         post code
 else:
        person_form = PersonForm(prefix='person')
        current_address_form = AddressForm(prefix='current_address')
        previous_address_form = AddressForm(prefix='previous_address')
        employment_form = EmploymentForm(prefix='employment')
        if pk is None:
            application_form = ApplicationForm(prefix='application')
        else:
            application_form = ApplicationForm(prefix='application', initial={'property': pk})
1 Like