2014-06-26 17 views
12

Ho bisogno di django modelform con 2 campi, in cui la seconda lista di scelta del campo dipende da cosa è stato scelto nel primo. Il mio modello:Campo di scelta del modello di Django - dipende dall'altra scelta del campo

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?? 

Come posso impostare scelte di fanno campo per PERSONAL_MAKES se VEHICLE_TYPE è impostato su personali? Come posso fare questo? È possibile a livello di modello?

risposta

4

Probabilmente non è possibile perché dipende dall'interazione dell'utente con il modulo: il server non può sapere in anticipo quale elemento verrà selezionato dall'utente prima di inviare il modulo al browser. Probabilmente potresti ottenere questo risultato usando ajax. Penso che un processo di lavoro potrebbe essere:

  • Creare un modulo con tutti i campi, e fare make campo hidden
  • creare una vista (lo chiamerò AjaxMakeFieldView) che cattura una richiesta AJAX prendere una vehicle_type argomento e restituire l'HTML per make field, popolato con dati rilevanti. Aggiungi un URL nel tuo URLConf per questa vista.
  • Nel modello, aggiungere un Javascript vincolante: quando l'utente seleziona un vehicle_type, il browser invia una richiesta aan Ajax per AjaxMakeFieldView e sostituire nascosta make campo con ritornato HTML

Se non si desidera javascript, un altro modo sarebbe una forma in due fasi:

  • un primo modulo con un campo vehicle_type
  • una volta che il primo modulo viene inviato, l'utente ottiene un secondo modulo con un campo make, che i dati iniziali vengono compilati in base a vehicle_type selezionati nel primo modulo.

Non l'ho mai fatto, ma Django documentation on Form wizard sembra un buon punto di partenza.

+0

soluzione JS va bene, ma mi avrebbe bisogno di qualche guida con esso.Cosa dovrei inizialmente rendere? – dease

+0

Ho modificato la mia risposta. Scusa per non aver fornito un esempio di codice, ma sono occupato ora. Se non ottieni ciò che vuoi, dimmelo, proverò a fornire maggiori dettagli. –

0

Questo è il modo in cui ho finito per avere due campi di scelta del modello a seconda dell'uno, su una pagina. In seguito, field2 dipende field1:

Javascript parte

Si noti che in $.each(), $.parseJSON(resp) non devono essere utilizzati (invece di json), come stiamo già averlo analizzato da jQuery (a causa alla risposta content_type = 'application/json') - vedi I keep getting "Uncaught SyntaxError: Unexpected token 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 parte views.py

Nota che questo può essere fatto probabilmente da django-riposo-struttura del sito. Sto ottenendo fields=('id', 'code', 'affection')) dal mio MyModel2 - questi possono quindi essere raggiunti in JQuery utilizzando 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') 
Problemi correlati