2

I have models.py, and forms.py that looks like this:

class BHA_overall(models.Model):
    bha_number = models.ForeignKey(BHA_List, 'CASCADE', related_name='bha_overall')
    drill_str_name = models.CharField(max_length=111)
    depth_in = models.CharField(max_length=111)
    depth_out = models.CharField(max_length=111)


class BHA_overall_Form(forms.ModelForm):
    class Meta():
        model = BHA_overall
        fields = '__all__'

In my template, if I just use:

<form method="POST">
  {% csrf_token %}
  {{ form.as_p }}
  <button name='action' value='login' type="submit">Sign in</button>
</form> 

the foreign key field bha_number is displayed as a combo box where I can select the specific bha_number model instance it belongs to, like this:

enter image description here

Here, I want to remove Bha number field from the user side, and just let my code auto fill that field for the user, and hide it. So from the user side, there will be only 3 fields displayed. How can I do this?

Currently I am implementing this html code:

<form id="demo-form" data-parsley-validate="" novalidate="" method="POST">
  <div class="row">
      {% csrf_token %}
      {% for field in form %}
      <div class="col-lg-2 col-md-2 col-sm-4 col-xs-6" style="margin-bottom: 5px">
        <label class="input-upper-title">{{ field.name }}</label>
        <input type="text" id="" class="form-control input-field-height-vertical" name="" data-parsley-trigger="" required="">
      </div>
      {% endfor %}
      <input type="submit" class='btn btn-primary' value="Submit">
  </div>
</form>

And it renders this:

enter image description here

I want the first field, bha_number to disappear from the user side, but the system still needs to get that information to save to a correct model instance. So I'm looking for an way to auto fill this ForeignKey field at forms.py or views.py level.

Here is my views.py:

class BHA_UpdateView(UpdateView):
    model = BHA_List
    success_url = reverse_lazy('well_list') # this is wrong
    form_class = BHA_overall_Form
    def post(self, request, **kwargs):
        api = get_well_api(self.request)
        current_bha = BHA_List.objects.filter(id=get_current_bha_id(self.request))[0]
        form = BHA_overall_Form(request.POST, instance=BHA_overall.objects.filter(bha_number__well__api=api, bha_number=current_bha)[0])
        if form.is_valid():
            form.save()
        return super().post(request, **kwargs)
Eric Kim
  • 2,493
  • 6
  • 33
  • 69

2 Answers2

4

You can use exclude to hide the field from form

Class BHA_overall_Form(forms.ModelForm):
    class Meta():
        model = BHA_overall
        fields = '__all__'
        exclude = ('bha_number',) 

To auto fill after checking if form is valid, just clean the data using form = form.cleaned_data and store it in any variable. It's nothing but a dictionary. You can assign value to this like form['bha_number'] = your value and save it to database by using form.save().
Or you can use object = form.save(commit=False) because this method will return an object. Then you can do object.bha_number = your number And finally object. Save in next line. That's all. Choose whatever solution you like.

Sam
  • 815
  • 10
  • 23
1

Why don't you keep it as is on forms.py but exclude it from your HTML? That way the user would not see it as an option but the value would still be sent with the form.

Maisha
  • 29
  • 3