Поле выбора модели Django - зависит от другого выбора поля

Мне нужна модель модели django с 2 полями, где второй список выбора поля зависит от того, что было выбрано в первом. Моя модель:

class Offer(BaseModel):

    VEHICLE_TYPES = (
        ('personal','Personal car'),
        ('truck','Truck'),
    )
    vehicle_type = models.CharField(max_length=32, choices=VEHICLE_TYPES, default='personal', verbose_name='Vehicle type')

    PERSONAL_MAKES = (
        ('',''),
    )
    TRUCK_MAKES = (
        ('',''),
    )
    make = models.CharField(max_length=32)#what more??

Как я могу задать выбор поля make для PERSONAL_MAKES, если для параметра vehicle_type установлено личное? Как я могу это сделать? Возможно ли это на уровне модели?

Ответ 1

Вероятно, вы не можете, потому что это зависит от взаимодействия пользователя с вашей формой: ваш сервер не может заранее знать, какой элемент будет выбран вашим пользователем перед отправкой формы в браузер. Вероятно, вы можете достичь этого, используя ajax. Я думаю, что рабочий процесс может быть:

  • Создайте форму со всеми полями и сделайте поле make hidden
  • Создайте представление (я назову его AjaxMakeFieldView), который поймает запрос ajax с аргументом vehicle_type и вернет HTML для make field, заполненный соответствующими данными. Добавьте URL-адрес в URLConf для этого представления.
  • В вашем шаблоне добавьте привязку Javascript: когда пользователь выберет vehicle_type, браузер отправит aan ajax-запрос на AjaxMakeFieldView и заменит скрытое make поле с возвращенным HTML

Если вы не хотите javascript, другой способ - это двухэтапная форма:

  • Первая форма с полем vehicle_type
  • После отправки первой формы ваш пользователь получит вторую форму с полем make, исходные данные которого заполняются в зависимости от vehicle_type, выбранного в первой форме.

Я никогда этого не делал, но Документация Django на Мастере форм кажется хорошим местом для начала.

Ответ 2

Таким образом, у меня было два поля выбора модели в зависимости друг от друга на одной странице. В ниже, field2 зависит от field1:

Часть Javascript

Обратите внимание, что в $.each(), $.parseJSON(resp) НЕ следует использовать (а не просто json), поскольку мы уже обрабатываем его jQuery (из-за ответа content_type = 'application/json) - см. Я продолжаю получать "Неиспользовать SyntaxError: Неожиданный токен o" .

$(document).ready(function() {

    $("#id_field2").empty();

    $("#id_field1").change(function(){

        $.ajax({
            url: "{% url 'ajax_get_field_2' %}",
            type: 'GET',
            data:  {field1_id: $("#id_field1").val()},
            dataType: "json",
            success: function(resp){
                $("#id_field2").empty();
                $.each(resp, function(idx, obj) {
                    $('#id_field2').append($('<option></option>').attr('value', obj.pk).text(obj.fields.code + ' (' + obj.fields.affection + ')'));
                });
            },
            error: function(jqXHR, textStatus, errorThrown) {
                alert(errorThrown);
            }
        });

    });
});

часть Django views.py

Обратите внимание, что это возможно, вероятно, также с помощью django-rest-framework. Я получаю fields=('id', 'code', 'affection')) из моего MyModel2 - это можно сделать в JQuery с помощью obj.fielsd.<myfieldname>.

class AjaxField2View(generic.View):

    def get(self, request, *args, **kwargs):
        field_1 = get_object_or_404(MyModel1, pk=request.GET.get('field1_id', ''))
        model2_results = MyModel2.objects.filter(k_value=field_1 .k_value)
        return HttpResponse(serializers.serialize('json', model2_results, fields=('id', 'code', 'affection')), content_type='application/json')