set default values in a fields (auto-fill)

Hi,
I have a record to save in the app database.
so I have created a table in models.py SurveillanceDesPuits as:

class SurveillanceDesPuits(models.Model):
    PUITS    =  models.ForeignKey(Surveill_Wells ,to_field='WellID', on_delete=models.CASCADE)
    DATE_TEST=  models.DateField()
    MODE     = models.CharField(max_length=6)
......
.....
    post_date   = models.DateTimeField(auto_now_add=True) 
    author      = models.CharField(max_length=15, default= User)
    def __str__(self):
        return self.PUITS.WellID
    def get_absolute_url(self):
        return reverse('WellMonitor')

and my formes.py is :


class SurveillanceDesPuits_F(forms.ModelForm):
    PUITS     =  forms.ModelChoiceField(required=False,label='Well ID', queryset=Surveill_Wells.objects.all())
    DATE_TEST =  forms.DateField(label='Control Date',widget=forms.DateInput(attrs={"class":"form-control", 'type':'date'}))
    MODE      = forms.CharField(label='Mode',max_length=6)
....
.....
    class Meta:
        model= SurveillanceDesPuits
        fields=('PUITS','DATE_TEST','MODE','CS','SITUATION','DUSE','PRES_TBG','PRES_CSG','PRES_AVD','RESEAU_GL','ANNULAIRE_TECH','OBSERVATION','Controle_Pression_ENSP','Test_Puits','Controle_Pression_DP')

So I have a view and the result is good.

and the record input page is like this:

what I need to do is auto-fill for example when I chose a well from the list
it fills the rest of the fields from the last record of the same well!

so is that possible or easy to do? and how to do it?

You need to implement chained fields, this tutorial will help you, but you will need to code endpoints that take the lasts values from Well and fill the form.

Most of the work will be at JavaScript level.

1 Like

I tried to do it like this.

def load_record(request):
    PUITS_id = request.GET.get('PUITS')
    record = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
    my_record= [str(record[0].PUITS) , str(record[0].MODE), str(record[0].CS)]
    print(my_record)
    return render(request, 'measure/Surveill_Wells/Add_wellMntr.html', {'record': my_record})

so it print in the console my_record is ['TFT1', 'GL', 'AMA'] which is the last record I need.

this is the data I need in the HTML page
and this is my HTML page

<form method="POST" id="SurveillanceDesPuits_F" data-record-url="{% url 'ajax_load_record' %}">
        {% csrf_token %}
          <!-- form  from views.py-->
        <div class="border p-2 mb-3 mt-3 border-secondary">
                    <div class="form-row">
                <div class="form-group col-md-3 mb-0">
                    {{ form.PUITS|as_crispy_field }}
                </div>
                <div class="form-group col-md-3 mb-0">
                    {{ form.CS|as_crispy_field }}
                </div>
                <div class="form-group col-md-3 mb-0">
                    {{ form.MODE|as_crispy_field }}
                </div>
            </div>
        </div>
        <input class="btn btn-success mb-4" type="submit" value="ADD Record">
    </form>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
  $("#id_PUITS").change(function () {
    var url = $("#SurveillanceDesPuits_F").attr("data-record-url");  
    var PUITSId = $(this).val();  
    $.ajax({                       
      url: url,                    
      data: {
        'PUITS': PUITSId       
      },
      success: function (data) {   
        $("#id_MODE").html(data);
      }
    });
  });
</script>

and here it gives me this error.

File "D:\WikiPED\venv\lib\site-packages\crispy_forms\templatetags\crispy_forms_filters.py", line 102, in as_crispy_field
    raise CrispyError("|as_crispy_field got passed an invalid or inexistent field")
crispy_forms.exceptions.CrispyError: |as_crispy_field got passed an invalid or inexistent field
[07/Sep/2021 17:30:05] "GET /ajax/load-record/?PUITS=1 HTTP/1.1" 500 25693

so what do I need to add in the code to set automatically the received data?

The above error is indicating that somewhere in the template that’s rendered as a part of the /ajaz/load-record/ request, the template filter, |as_crispy_field is being used, but the field being passed into it (the left hand side of the | character) is invalid. My guess is that the field is resolving to None because it’s not being passed some expected context.

Start with reviewing measure/Surveill_Wells/Add_wellMntr.html and see what context is needed, then pass that in load_record’s call to render.

Hi After many days of trying to solve this issue.
I get this code which is not working well but need to make the form refresh:
so first my URL is:

path(‘Add_wellMntr/’, MeasureV.CreateWellMon, name=‘Add_wellMntr’),

and the HTML page is like this:


> {% if form %}
> <div class="border p-3 mb-3 mt-3 w3-round-large w3-light-grey border-dark">
>     <form method="POST" id="SurveillanceDesPuits_F" data-record-url="{% url 'Add_wellMntr' %}">
>         {% csrf_token %}
>           <!-- form  from views.py-->
>         <div class="border p-2 mb-3 mt-3 border-secondary">
>                     <div class="form-row">
>                 <div class="form-group col-md-3 mb-0">
>                     {{ form.PUITS|as_crispy_field }}
>                 </div>
>                 <div class="form-group col-md-3 mb-0">
>                     {{ form.CS|as_crispy_field }}
>                 </div>
>                 <div class="form-group col-md-3 mb-0">
>                     {{ form.MODE|as_crispy_field }}
>                 </div>
>             </div>
>             <div class="form-row">
>                 <div class="form-group col-md-3 mb-0">
>                     {{ form.PRES_TBG|as_crispy_field }}
>                 </div>
>             </div>     
> <hr>
>         </div>
>         <input class="btn btn-success mb-4" type="submit" value="ADD Record">
>     </form>
>     </div>
> {% endif %}
> 
> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
> <script>
>   $("#id_PUITS").change(function () {
>     var url = $("#SurveillanceDesPuits_F").attr("data-record-url");  // get the url of the `load_record` view
>     var PUITSId = $(this).val();  // get the selected PUITS ID from the HTML input
>     $.ajax({                       // initialize an AJAX request
>       url: url,                    // set the url of the request (= localhost:8000/hr/ajax/load-record/)
>       data: {
>         'PUITS': PUITSId       // add the PUITS id to the GET parameters
>       },
>       success: function (record) {   // `data` is the return of the `load_record` view function
>       }
>     });
>   });
> </script>
> {% endblock content %}

Here I add a java function to recall the function CreateWellMon via the URL Add_wellMntr

so everything works well I can add new wells using this code and the views.py :slight_smile:

def CreateWellMon(request):
    if request.method == 'POST':
        form = SurveillanceDesPuits_F(request.POST or None)
        if form.is_valid():
            form.instance.author = request.user
            form.save()
            return redirect('Welltesting')
    else:
        try:
            PUITS_id = request.GET.get('PUITS')
            record = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
            record2 = SurveillanceDesPuits.objects.get(id= record[0].id)
            print( record2.PUITS ,record2.MODE, record2.CS, record2.PRES_TBG,)
            form = SurveillanceDesPuits_F(instance=record2)
            return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})
        except:
            record2 = SurveillanceDesPuits.objects.get(id= 12)
            form = SurveillanceDesPuits_F(instance=record2)
            return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})

so when I open the page for the first time it gives me the id= 12 data and it works very well.
then when I select an element from the list my java code executes the function CreateWellMon again and it prints the related data in the console to check.

TFT1 E AMA 30
[09/Sep/2021 17:58:37] "GET /Add_wellMntr/?PUITS=1 HTTP/1.1" 200 31010
TFT39 GL AMA 11
[09/Sep/2021 17:58:44] "GET /Add_wellMntr/?PUITS=34 HTTP/1.1" 200 31015
TFT10 SRP AMA 25
[09/Sep/2021 17:59:04] "GET /Add_wellMntr/?PUITS=9 HTTP/1.1" 200 31012

the only problem is the HTML doesn’t refresh the data so how could I do this?
any hint or trucs?

Your success function needs to update the DOM with the data received from the server.

I can delete this line the most important is how I reload the data in fields?
I think it is related to back-end I need to something in the views.py function!
thanks

No, it has nothing to do with the back end.

Your AJAX request is asking the server for “something” - either JSON data or an HTML fragment. The server is then returning that data to your JavaScript function that made the call.

What happens to that data after it has been returned is strictly up to what the JavaScript does with it. It’s up to you to know what the server is returning and how it fits into the existing page, and to provide the code to perform the updates.

I deleted this line so I just want to re-call the function using AJAX no need for its data.
then python returns new data that I need to show in fields as it gives me the first time that’s my point.

    else:
        try:
            PUITS_id = request.GET.get('PUITS')
            record = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
            record2 = SurveillanceDesPuits.objects.get(id= record[0].id)
            print("in Try", record2.PUITS ,record2.MODE, record2.CS, record2.PRES_TBG,)
            form = SurveillanceDesPuits_F(instance=record2)
            return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})
        except:
            record2 = SurveillanceDesPuits.objects.all().first()
            print( record2.PUITS ,record2.MODE, record2.CS, record2.PRES_TBG,)
            form = SurveillanceDesPuits_F(instance=record2)
            return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})

see here I asked to load the first entry in my database then I select an element the AJAX executes the function again and reload the asked data but it doesn’t refresh it on the page.

Yes you do need the data if you’re going to update the page.

Correct. It’s not going to update the page unless you write the appropriate JavaScript code within the success function to update the page.

Django has no control over what the browser does with data sent to it.

When the browser is requesting a full page, Django sends a full page. It’s the browser, not Django, that renders the page on the screen.
When the browser (via JavaScript AJAX call) requests part of a page, or data, Django sends the requested data. Then it’s still up to the browser (JavaScript in this case) to do something with it.

then for me it is impossible (worst coding is AJAX and java you should write a book to execute a function).
think I will paid someone to do for me. and tell you.
many thanks

@smailt If you need help in frontend I can do the job. Contact me if you are interested.

1 Like

Yes I need, how could I contact you?

Hi, again
Now and after I had tried many solutions, I am able to set default values of the form fields.
so when I enter to adding new record page I get default values of the last record as the image illustrates.

the changes made in the script are:

<script type="text/javascript">
$(document).ready(function(){
    $("#id_PUITS").change(function(){
    var url = $("#SurveillanceDesPuits_F").attr("data-record-url");  
    var PUITSId = $(this).val();
    $.ajax({
        type: 'GET' ,              
        url: url,              
        data: {

          'PUITS': PUITSId    
                 },
        success: function (data){
        $('#SurveillanceDesPuits_F').html(data);
        }
        });
});
});
</script>

the results are good and the script calls the new data but with some problems.

so after I select a Well ID the code load the new data but it duplicates some elements, see the above pic.
2nd problem is it doesn’t keep the selected Well ID in the choice field.

how could I fix that?
All my best

The snippet of JavaScript you’ve provided here looks fine. The issues you’re describing are not likely caused by it.

With an AJAX call, you want the view that you’re calling to return just a fragment of a page, not a whole page.

This also means that the template being used to render that fragment probably won’t extend any templates. You want it to just render the html being replaced.

As a result, the view being used to get the fragment should likely be a different view than that used to generate the page.

If that page fragment needs a parameter to populate the fragment, it needs to be supplied as part of the request.

We’d need to see the views and templates involved to be able to offer any more specific suggestions.

I solved the 2nd problem by deleting the to_field='WellID' in the models.py (SurveillanceDesPuits)

Now, still, just the duplicated problem, and this issue will be solved completely.

All my best

I get the solution,
the first change is in models.py:

class SurveillanceDesPuits(models.Model):
    PUITS    =  models.ForeignKey(Surveill_Wells , on_delete=models.CASCADE)
    DATE_TEST=  models.DateField()
    ....

then I changed the views.py:

def CreateWellMon(request):
    if request.method == 'POST':
        form = SurveillanceDesPuits_F(request.POST or None)
        if form.is_valid():
            form.instance.author = request.user
            form.save()
            return redirect('WellMonitor')
    else:
        try:
            PUITS_id = request.GET.get('PUITS')
            record2 = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
            return JsonResponse({'record2': list(record2.values())}, safe=False)
        except:
            form = SurveillanceDesPuits_F()
            return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})

First I made a change in models.py, I deleted to_field='WellID' , so it will keep the selected well after the AJAX call.

class SurveillanceDesPuits(models.Model):
    PUITS    =  models.ForeignKey(Surveill_Wells , on_delete=models.CASCADE)
    DATE_TEST=  models.DateField()
    ....

then I changed the views.py:

def CreateWellMon(request):
    if request.method == 'POST':
        form = SurveillanceDesPuits_F(request.POST or None)
        if form.is_valid():
            form.instance.author = request.user
            form.save()
            return redirect('WellMonitor')
    else:
        try:
            PUITS_id = request.GET.get('PUITS')
            record2 = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
            record2_seri = serializers.serialize('json', record2)
            return JsonResponse(record2_seri, safe=False)
        except:
            form = SurveillanceDesPuits_F()
            return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})

the last change is in the HTML page and the ajax code call will be as:

<script type="text/javascript">
        $.ajax({ 
            type: 'GET' ,               
            url: url,              
            data: {'PUITS': PUITSId },
            dataType: "json",
            success: function (response){           
                var  response = JSON.parse(response);
                const object = response[0]
    
                $("#id_PUITS").val(object.fields.PUITS);
                $("#id_DATE_TEST").val(object.fields.DATE_TEST);
                $("#id_MODE").val(object.fields.MODE);
                $("#id_CS").val(object.fields.CS);
                $("#id_SITUATION").val(object.fields.SITUATION);
                $("#id_DUSE").val(object.fields.DUSE);
                $("#id_PRES_TBG").val(object.fields.PRES_TBG);
                $("#id_PRES_CSG").val(object.fields.PRES_CSG);
                $("#id_PRES_AVD").val(object.fields.PRES_AVD);
                $("#id_RESEAU_GL").val(object.fields.RESEAU_GL);
                $("#id_ANNULAIRE_TECH").val(object.fields.ANNULAIRE_TECH);
                $("#id_OBSERVATION").val(object.fields.OBSERVATION);
                $("#id_Controle_Pression_ENSP").val(object.fields.Controle_Pression_ENSP);
                $("#id_Test_Puits").val(object.fields.Test_Puits);
                $("#id_Controle_Pression_DP").val(object.fields.Controle_Pression_DP);
            },
    
            });
            return false;
            });
    </script>

Thank you all for your help