2016-01-13 2 views
0

У меня есть модель, в которой хранятся различные типы данных (дискретные или непрерывные значения) в одном поле (с типом в другом). В ModelForm для этой модели у меня есть ChoiceField, чтобы выбрать элемент данных, и либо ChoiceField, либо DecimalField, чтобы установить значение элемента.реагировать на действия пользователя в форме администратора django?

Когда я создаю форму, я устанавливаю поле для значения в соответствии с типом элемента. Но если я выберу элемент другого типа, я хотел бы сразу изменить поле значения для соответствия.

Я не могу найти способ ответить на изменение, пока форма все еще активна, т. Е. Когда пользователь меняет значения полей, но не нажал кнопку «Отправить». Есть ли способ сделать это? Предпочтительно оставаться на Python на сервере, а не на стороне браузера, кодируя его в javascript.

Варианты выбора ChoiceField взяты из модели, поэтому они не могут быть жестко закодированы в любом месте.

Вот код:

class FooProperty (models.Model): 
    foo  = models.ForeignKey ('foos.Foo') 
    prop = models.ForeignKey ('foos.FooProperty') 
    value = models.DecimalField (max_digits=15, decimal_places=6) # is an EnumValue id in the case of discrete values. 

class FooPropertyForm (forms.ModelForm): 
    class Meta: 
     model = FooProperty 
     fields = ['prop', 'value'] 

    def __init__(self, *args, **kwargs): 
     super (FooPropertyForm, self).__init__(*args, **kwargs) 

     if hasattr (self.instance, 'prop'): 
      kind = self.instance.prop.units.kind 
      if kind.id != 1: 
       values = [(v.id, v.name) for v in EnumValues.objects.filter (kind=kind.id)] 
       self.fields ['value'] = forms.ChoiceField (choices=values, required=True) 
       self.initial['value'] = int(self.instance.value) # using initial= above doesn't work. 
      else: 
       # keep the default field. 
       pass 

ответ

0

У меня похожая полиморфный модель, которая хранит различные типы значений (строка, INT, десятичной, и т.д.) на основе его типа.

Не могли бы вы немного разъяснить свой вопрос? Вы говорите «если я выбираю элемент другого типа». Вы имеете в виду, изменив поле формы в своем браузере или в своем коде?

Предполагаю, вы имеете в виду первое. Невозможно реагировать на изменения живой формы на Python без какой-либо асинхронной связи с клиентской стороны.

В моем приложении, это процесс 2 этапа:

  1. Пользователь в выбирает тип
  2. На стороне клиента, обработчик изменений на этом поле типа запускает вызов для извлечения тип- конкретные поля формы. Существует отдельное представление Django, которое создает отдельную форму с кучей типов и логики типа.

var $kind = $('#kind'); 
 

 
$kind.on('change', fetchFormFieldsForKind); 
 

 
function fetchFormFieldsForKind() { 
 
    var kind = $kind.val(); 
 
    $.get(
 
    "{% url 'form_fields_for_kind' %}?kind=" + $kind.val(), 
 

 
    function (response) { 
 
     newFieldsHtml = response.newFieldsHtml || ''; 
 

 
     // Replace all following sibling form fields with the new ones 
 
     // (each field is wrapped by a div with Bootstrap class form-group) 
 
     $kind.closest('.form-group').find('~ .form-group').remove(); 
 
     $kind.after(newFieldsHtml); 
 

 
     // or replace the whole form with a rendered ModelForm 
 
    } 
 
); 
 
}

Для полноты, что Джанго вид будет выглядеть примерно так:

def form_fields_for_kind(request, kind): 
    """ 
    Given the string 'kind', return a rendered form that contains 
    any type-specific fields. 
    """ 
    form = YourForm(kind=kind) 
    content = form.as_p() 
    return HttpResponse(content, 'text/html') 
Смежные вопросы