2016-09-20 2 views
0

Ich habe ein Bestellformular, wo der Benutzer einen Artikel auswählen und eine Menge auswählen kann. Der Preis hängt davon ab, wie viel bestellt wird. Zum Beispiel ist jeder Artikel $ 10, wenn Sie < 100 bestellen, aber $ 7, wenn Sie 100-200 bestellen.Wählen Sie den umgekehrten Fremdschlüssel in ModelChoicefield

In der Vorlage möchte ich die Preisinformationen unterhalb des Formulars für jede Auswahl anzeigen.

Das sind meine Modelle:

class Product(models.Model): 
    name = models.TextField() 

class Price(models.Model): 
    """ 
     This lets us define rules such as: 
     When ordering <100 items, the price is $10 
     When ordering 100-200 items, the price is $7 
     When ordering 200-300 items, the price is $5 
     etc 
    """ 
    price = models.FloatField() 
    min_quantity = models.PositiveIntegerField() 
    max_quantity = models.PositiveIntegerField() 
    product = models.ForeignKey(Product) 

class Order(models.Model): 
    product = models.ForeignKey(Product, null=False, blank=False, default='') 
    quantity = models.IntegerField() 

Ich kann die Formularfelder geschleift und die queryset unabhängig:

{% for choice in form.product.field.queryset %} 
    <h1>{{choice}} {{choice.price_set.all}}</h1> 
{% endfor %} 

{% for choice in form.product %} 
    <h1>{{ choice.tag }} {{ choice.choice_label }}</h1> 
{% endfor %} 

... aber ich weiß nicht, wie die Schleifen zu kombinieren, um Zeigen Sie die Preise unterhalb der Formularfelder an.

Im Wesentlichen möchte ich einen umgekehrten Fremdschlüssel aus einem ModelChoicefield Widget auswählen. Ich muss entweder die Formularfelder und das Abfrage-Set gleichzeitig durchlaufen oder auf Elemente im Abfrage-Set über das Formularelement zugreifen. Idealerweise ist das, was ich in meiner Vorlage tun möchte:

{% for choice in form.product %} 
    <h1>{{ choice.tag }} {{ choice.choice_label }}</h1> 
    {% for price in choice.price_set.all %} 
     <h1>{{price}} etc...</h1> 
    {% endfor %} 
{% endfor %} 

Sicher bin ich nicht die erste Person mit diesem Anwendungsfall. Was ist der beste Weg, dies zu tun?

Bearbeiten: Wie gewünscht, das ist meine Form und meine Sicht. Wenn ich das hier wiederhole, hätte ich erwähnen sollen, dass ich das RadioSelect Widget verwende.

Form:

class OrderForm(forms.ModelForm): 
    class Meta: 
     exclude = ['date_added'] 
     widgets = { 
      'mailer': forms.RadioSelect 
     } 
     model = Order 

Ausblick:

def processOrder(request): 
    if request.method == 'POST': 
     orderForm = OrderForm(request.POST) 
     if orderForm.is_valid(): 
      orderObject = orderForm.save() 
      return render(request, TEMPLATE_PREFIX + "confirm.html", {"orderObject": orderObject}) 
     else: 
      return render(request, TEMPLATE_PREFIX + "register.html", { "form": orderForm }) 
    else: 
     return render(request, TEMPLATE_PREFIX + "register.html", { "form": OrderForm()}) 
+0

Könnten Sie Ihren Formularcode (Form + View) posten? – vmonteco

+0

Fertig. Siehe oben. – Travis

Antwort

0

Für (nicht) Perfektionisten mit Fristen, dieser Code funktioniert, wenn auch ineffizient.

{% for choice in form.product %} 
    {% for price_candidate in form.mailer.field.queryset %} 
     {% if price_candidate.id == choice.choice_value|add:0 %} 
      <h1>{{ choice.tag }} {{ choice.choice_label }}</h1> 
      {% for price in price_candidate.price_set.all %} 
       <h1>{{price}} etc...</h1> 
      {% endfor %} 
     {% endif %} 
    {% endfor %} 
{% endfor %} 

(Der add:0 Hack wandelt choice_value in einen int. Cf http://zurb.com/forrst/posts/Compare_string_and_integer_in_Django_templates-0Az)

Verwandte Themen