简体   繁体   中英

How to render a piece of data stored in an external model without refreshing the page?

I am trying to display a User's name on top of a box where they enter their Employee # in a form, without having to refresh the page.

For example, they enter their # and then after they click/tab onto the next field, it renders their name on top, which comes from the database, so the user knows they've entered the correct info. This name is stored in a separate model, so I try to retrieve it using the "id/number".

I am not too familiar with AJAX but after reading a few similar questions it seems like an AJAX request would be the most appropriate way to achieve this. I tried to make a function get_employee_name that returns the name of the person based on the way I saw another ajax request worked, but I'm not sure how to implement this so it displays after the # is entered.

models.py

class EmployeeWorkAreaLog(TimeStampedModel, SoftDeleteModel, models.Model):
    employee_number = models.ForeignKey(Salesman, on_delete=models.SET_NULL, help_text="Employee #", null=True, blank=False)
    work_area = models.ForeignKey(WorkArea, on_delete=models.SET_NULL, null=True, blank=False)
    station_number = models.ForeignKey(StationNumber, on_delete=models.SET_NULL, null=True,  blank=True)

    def __str__(self):
        return self.employee_number

This is the model where the name is stored

alldata/models.py

class Salesman(models.Model):
    slsmn_name = models.CharField(max_length=25)
    id = models.IntegerField(db_column='number', primary_key=True)

I was reading I can add to the "attrs" in the widget an 'onchange' part, but I am not too familiar with how to approach this and tying it to the ajax request from forms and not the html.

forms.py

class WarehouseForm(AppsModelForm):
    class Meta:
        model = EmployeeWorkAreaLog
        widgets = {
            'employee_number': ForeignKeyRawIdWidget(EmployeeWorkAreaLog._meta.get_field('employee_number').remote_field, site, attrs={'id':'employee_number_field'}),
        }
        fields = ('employee_number', 'work_area', 'station_number')

views.py

class EnterExitArea(CreateView):
    model = EmployeeWorkAreaLog
    template_name = "operations/enter_exit_area.html"
    form_class = WarehouseForm

    def form_valid(self, form):
        # do submission stuff..


def get_employee_name(request, id):
    employee = get_object_or_404(Salesman, id=id)
    return HttpResponse(employee.slsmn_name)

urls.py

urlpatterns = [
    url(r'enter-exit-area/$', EnterExitArea.as_view(), name='enter_exit_area'),

    path('get-employee-name/<int:id>/', views.get_employee_name, name='ajax_get_employee_name'),
]

The ajax request I tried to create is at the end of this html. I modified a similar request I found, but it does not actually display anything on the screen, not sure if I'm missing an area where the request is actually never being called, as I am not too familiar with how these types of requests work.

enter_exit_area.html

{% extends "base.html" %}

{% block main %}
    <form id="warehouseForm" action="" method="POST" novalidate >
        {% csrf_token %}
        <div>
            <h1 id="url" get-employee-name-url="{% url 'operations:ajax_get_employee_name' %}">{{ employee_name }}</h1>
            <div>
                {{ form.employee_number.help_text }}
                {{ form.employee_number }}
            </div>
            <div>
                {{ form.work_area.help_text }}
                {{ form.work_area }}
            </div>
        </div>

        <div>
            <div>
                <button type="submit" name="enter_area" value="Enter">Enter Area</button>
            </div>
        </div>
    </form>

    <script>
        $("#id_employee_number").change(function () {
            var employee_number = $(this).val();
            var url = '/enter-exit-area/get-employee-name/' + employee_number;

            $.ajax({
            url: url,
            type:'GET',
            data: {
                'id': employee_number
            },
            success: function (data) {
                var employee_name = data['employee_name'];
                $('#employee_name')[0].innerHTML = employee_name;
            },
            error : function (data) {
                var error_message = data['error'];
                $('#employee_name')[0].innerHTML = error_message;
            }
            });
        });
    </script>

{% endblock main %}

What could be causing nothing to render on the page? I assume there needs to be a place where the onchange() goes, but I'm not sure where this would be in since the form fields are it's own thing, without tags.

Since you're defining you endpoint in the urlpatterns[] as follows:

path('get-employee-name/<int:id>/', views.get_employee_name, name='employee_name'),

the associated view should expect id a second parameter following request ; for example:

from django.http import HttpResponse
from django.shortcuts import get_object_or_404


def get_employee_name(request, id):
    employee = get_object_or_404(Salesman, id=id)
    return HttpResponse(employee.slsmn_name)

In the ajax call, I would rather use an absolute url:

var url = '/get-employee-name/' + employee_number;

(please note the leading backslash) otherwise, the visited url would be relative to the current page; If the app's urlpatterns in included in the root one with a suffix, add it as required:

var url = '/the_app/get-employee-name/' + employee_number;

Also, you don't need 'data' in the ajax call parameters, since you're expecting the employee_number from the url.

Finally, I would add:

console.log('data: %o', data)

to the success callback to make sure you're receiving what you expect

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM