Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About Django RadioSelect initial value

Tags:

python

django

Sorry for such a lame question, but I can't set an initial value for a field in ModelForm. It looks like this:

class OrderRegisterForm(forms.ModelForm):

    class Meta:
        model = Order
        widgets = {
            'weight_units': forms.RadioSelect,
        }

And in the model:

class Order(models.Model):

    WEIGHT_UNIT_CHOICES = (
        ('KG', 'kg'),
        ('TN', 't'),
    )

    weight_units = models.CharField(
        max_length=2,
        choices=WEIGHT_UNIT_CHOICES,
        default="KG"
    )

But then I'm trying to render it in a template like this

<ul class="form__row__list">
{{ order_form.weight_units }}
</ul>

correct values appear, but radio button with default value is not selected. I tried to pass an initial argument, override __init__ in form and so on, but still nothing works.

UPDATE

as_p() provides the correct result. Things are getting weird.

<p>
<label for="id_weight_units_0">Weight units:</label>
<ul id="id_weight_units">
    <li>
        <label for="id_weight_units_0"><input checked="checked" id="id_weight_units_0" name="weight_units" type="radio" value="KG" /> kg</label>
    </li>
    <li>
        <label for="id_weight_units_1"><input id="id_weight_units_1" name="weight_units" type="radio" value="TN" /> t</label>
    </li>
</ul>

Please, show me my mistake.

like image 861
Enchantner Avatar asked Jan 31 '26 03:01

Enchantner


2 Answers

According to this Question here: default value for django choice field

you have to do the following: https://stackoverflow.com/a/22257696/659900

Use the default attribute:

display = models.CharField(..., default=FRIENDS)

or

display = models.CharField(..., default=CHOICES[1][1])

* UPDATE *

I have taken your code and I have tried to reproduce your error. But unfortunately your code does work.

Here is what I've done

models.py

class Order(models.Model):

    WEIGHT_UNIT_CHOICES = (
        ('KG', 'kg'),
        ('TN', 't'),
    )

    weight_units = models.CharField(
        max_length=2,
        choices=WEIGHT_UNIT_CHOICES,
        default="TN"
    )

forms.py

class OrderRegisterForm(ModelForm):

    class Meta:
        model = Order
        widgets = {
            'weight_units': RadioSelect,
        }

I have used the shell to see what HTML was produced:

>> from playground.test_app.forms import OrderRegisterForm

>> o = OrderRegisterForm()
>> o.as_p()

which gave me the following output (formatted for clarity):

<p>
  <label for="id_weight_units_0">Weight units:</label> 
  <ul>\n
    <li>
      <label for="id_weight_units_0">
       <input type="radio" id="id_weight_units_0" value="KG" name="weight_units" />
         kg</label>
     </li>\n
     <li>
       <label for="id_weight_units_1">
         <input checked="checked" type="radio" id="id_weight_units_1" value="TN" name="
weight_units" /> 
         t</label>
      </li>\n
    </ul>
  </p>  

I have set the default to "TN" on purpose, to make sure django doesn't use the first element by accident. See the checked="checked" attribute, that Django actually does use the right default value. Do you have some funny Javascript in place that might alter your output?

So could you please provide the output of your .as_p() method?

This might clarify a lot of things.

like image 153
Dr.Elch Avatar answered Feb 01 '26 16:02

Dr.Elch


So, I found the solution. The thing was I'm passing request.GET as is into form constructor and it seems to completely override initial values for fields. So, if you do

f = Form(request.GET)

the issue above happens. To avoid it, possible proper code is:

if request.method == "GET":
    form = Form()
    for key in request.GET:
        if key in form.fields:
            form.fields[key].initial = request.GET[key]
like image 30
Enchantner Avatar answered Feb 01 '26 15:02

Enchantner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!