Dropdown with dynamic options in Django form

Asked

Viewed 246 times

1

I have an expense form that has a field to select the category, but I need the options to be obtained from the database.

These days this is mine forms.py:

from django import forms
from .models import Expense

class ExpenseForm(forms.ModelForm):
    class Meta:
        model = Expense
        fields = '__all__'

In the views.py can create a query to return the categories:

def get_expense_categories():
    with connection.cursor() as cursor:
        cursor.execute(""" select * from units_accountplan;""")

        categories = dictfetchall(cursor)

This table units_accountplan has a simple structure:

id | Category

1 | Petrol

2 | Electricity

You can use this query to fill in the form options, or some other way to do this?

  • This table is inside Django’s data models or is outside the application?

  • is outside the application, is another Django project that shares the same database, so I can not access directly by model

  • Since it is a database of another application the most appropriate solution would be to create a REST API in the first application providing the table data accountplan, hence recover this data directly in HTML via Javascript (It is that I am considering the fact that one day these two applications may no longer be in the same DBMS).

1 answer

2

Taking into account that the Model of AccountPlan is set within an application your call units within the same database, you would need to do the following in your forms.py:

from django import forms
from .models import Expense
from units.models import AccountPlan

class ExpenseForm(forms.ModelForm):
    accountplan = forms.ModelChoiceField(
        queryset=AccountPlan.objects.all(),
        label='Account Plan',
        widget=forms.Select
    )

    class Meta:
        model = Expense
        fields = '__all__'

Now case the table accountplan is in a different database you can map this second database using multi-db and map the table accountplan as a normal Model Django, taking care to define Meta.managed = False and enter the name of the table in the model. For example:

class AccountPlan(models.Model):
    id = models.BigIntegerField(primary_key=True)
    data = models.DateField(blank=True, null=True)
    descricao = models.CharField(max_length=255, blank=True, null=True)
    nome = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'units_accountplan'

After this you can use the form as shown above, importing your new Model.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.