5

I need to pass the value (based on category_id) for a ForeignKey to the ModelForm but it's not working. My field remains "--------" and proper value is not set from the drop-down field. Value for the Category must BE SELECTED and other values must be not hided from user to choice.

As the result category value successfuly passed to template but drop-down field Category not set!

As I can see other guys solved it via constructor for ModelForm, but I feel there must be native django solution.

Would be thankful for any solutions!

my models.py:

class Category(models.Model):
    name = models.CharField('Name', max_length=20)
    icon = models.CharField('Icon', blank=True, max_length=20)

class Transaction(models.Model):
    type = models.CharField('Type', default='exp', max_length=20)
    category = models.ForeignKey(Category, on_delete=models.DO_NOTHING)
    note = models.CharField('Note', blank=True, max_length=20)

my urls.py:

urlpatterns = [
url(r'^add/(?P<category_id>[0-9]+)', "core.views.add_trans_view", name='add_trans_url'),
]

my views.py:

def add_trans_view(request, category_id):
    category = Category.objects.get(id=category_id)
    form = TransactionForm(request.POST or None, initial={'category':category.name,})
    if form.is_valid():
        instance = form.save(commit=False)
        instance.save()
        return render(request,
            'core/transaction_form.html', {'form': form, 'for_debug':category})

my forms.py:

class TransactionForm(forms.ModelForm):
class Meta:
    model = Transaction
    fields = ['type', 'category', 'note']

my template:

<p>Initial 'category' value transfered from view:</p>
<h4>{{for_debug}}</h4>
<form method='POST' action=''> {% csrf_token %}
  {{form.as_p}}
  <input type='submit' value='Done'/>    
</form>

1 Answers1

5

Try replacing

form = TransactionForm(request.POST or None, initial={'category':category.name,})

with

form = TransactionForm(request.POST or None, initial={'category':category,})

initial needs the instance (category), instead of only the string that contains its name (category.name).

LostMyGlasses
  • 3,074
  • 20
  • 28
  • Just a warning, be careful of your browser's cache. In my case, It showed the previous selected item and wouldn't update. Wasted a lot of my time. – OMY Jan 04 '23 at 20:59