Самый простой способ обновить значения модели, используя Django с формой AJAX - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть модель django, которая содержит несколько полей со связанными вариантами:

class Product(models.Model):
    CONDITION_CHOICES = (
        ("GOOD", "Good"),
        ("BAD", "Bad"),
        ("UNKNOWN", "Unknown"),
    )

    name = models.CharField(max_length=200, blank=True, null=True)
    colour = models.CharField(max_length=200, blank=True, null=True)

    condition = models.CharField(max_length=20, choices=CONDITION_CHOICES, blank=True, null=True)
    condition_source = models.CharField(max_length=20, blank=True, null=True)
    condition_last_updated = models.DateTimeField(blank=True, null=True)

У меня также есть форма, управляемая загрузчиком, которая выглядит следующим образом:

<div class="form-group">
    <label class="control-label"><strong>Condition</strong></label>
    <br/>
    <div class="btn-group btn-group-toggle" data-toggle="buttons">
        <label class="btn btn-outline-primary">
            <input type="radio" name="condition" value="GOOD" autocomplete="off">
            Good
        </label>
        <label class="btn btn-outline-primary">
            <input type="radio" name="condition" value="BAD" autocomplete="off">
            Bad
        </label>
        <label class="btn btn-outline-primary">
            <input type="radio" name="condition" value="UNKNOWN" autocomplete="off">
            Unknown
        </label>
    </div>
</div>

Я пытаюсь сделатьтак, что когда пользователь нажимает на одну из кнопок в пользовательском интерфейсе, модель Продукта обновляется (в частности, поля condition, condition_source и condition_last_updated).Фактическая модель имеет несколько полей, связанных с опциями выбора, поэтому я бы хотел, чтобы модель обновлялась в режиме реального времени без перезагрузки страницы, когда пользователь работает с формой.

Любое руководство будет оценено здесь - яПосмотрел intercooler.js, но не уверен, что это правильный инструмент для работы.

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Поскольку вы не указали, что condition_source должно включать, я установил его в строку some_source

Ajax:

$('.btn').on('click', function(){
    $.post(
           '/your_vew/',
           {
             'source': "some_source",
             'condition': $(this).find('input').val(),
             'csrfmiddlewaretoken': '{{csrf_token}}'
           },
           function(data){
              console.log(data.response);
           }
     );    
});  

urls.py:

urlpatterns = [
    ...
    path('your_vew/', views.your_view), 
    ...
]

views.py:

from django.http import JsonResponse
from datetime import datetime

def your_view(request):
    data = {'response': ''}
    if request.method == 'POST':
        p1 = Product.objects.filter(pk=1).update(
              condition_source=request.POST.get('source'),
              condition=request.POST.get('condition'),
              condition_last_updated=datetime.now()
            )
        if p1:
            data['response'] = 'Record updated!'    
    return JsonResponse(data) 
0 голосов
/ 08 февраля 2019

Теперь у вас есть несколько вариантов.Что я сделал, так это то, что я использовал ajax-метод Jquery в форме класса и настроил свои функции для своих приложений внутри этого класса.Django требует токен csrf для обработки входящих запросов.Итак, я нашел эти две функции, которые получают токен cookie csrf от клиента.

    function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

Как только токен csrf будет сохранен в переменной, вам нужно передать его функции ajax beforeSend, например, так:

ajax_setup(enable_async){
    enable_async = true;
    $.ajaxSetup({
    async: enable_async,
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        }
    }
    });
}
}

Полный запрос ajax будет чем-токак

update_user_language(user_id, lang, callback){
    this.ajax_setup(true);
    $.ajax({
        url: this.url,
        type: "POST",
        data: {
            'user_id':user_id,
            'lang':lang,
        },
        dataType: 'json',
        success: function(data){
            db_request_after();
            if(callback !== undefined) callback(data);
        },
        error: function(){
            db_request_error();
        },
    });
}

Обратите внимание на переменную обратного вызова.Это позволяет ajax вызывать функцию, передающую данные, полученные из веб-службы.

После того, как вы отправили запрос, вам нужно настроить view.py для принятия запроса и обработки переменных POST.

def sample_view(request):
   if request.method == "POST"
       user_id = request.POST.get('user_id')
       lang = request.POST.get('lang')
       #update the model value
       user = User.objects.get(pk=user_id)
       user.language = lang
       user.save()
       return JsonResponse({'message':'user updated'})
   else:
       return render(...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...