2016-09-08 3 views
0

Ich habe folgende drei Beziehungen:bekommt Wert von dinstinct Objekt für Auswahlfeld in django Form

class Size(models.Model): 
    amount = models.IntegerField(default=0) 
    unit = models.CharField(max_length=64) 
    created_at = models.DateTimeField(auto_now_add = True) 
    updated_at = models.DateTimeField(auto_now = True) 

    def __str__(self): 
     return str(self.amount) + ' ' + self.unit + ' size' 


class Sku(models.Model): 
    product = models.ForeignKey(Product) 
    size = models.ForeignKey(Size) 
    style = models.ForeignKey(Style) 
    price = models.DecimalField(max_digits=8, decimal_places=2) 
    created_at = models.DateTimeField(auto_now_add = True) 
    updated_at = models.DateTimeField(auto_now = True) 

    def __str__(self): 
     return self.product.name 

class ProductImage(models.Model): 
    product = models.ForeignKey(Product) 
    title = models.CharField(max_length=128, blank=True, null=True) 
    image = models.ImageField(upload_to='products', blank=True, null=True) 
    created_at = models.DateTimeField(auto_now_add = True) 
    updated_at = models.DateTimeField(auto_now = True) 

    def __str__(self): 
     return self.product.name 

Ich möchte alle Größen zeigen, dass Fremdschlüssel von SKUs als Auswahlmöglichkeiten in einer Modellform sind.

ich das versucht:

class SkuForm(forms.ModelForm): 


    def __init__(self, *args, **kwargs): 
     product = kwargs.pop('product', None) 
     super(SkuForm, self).__init__(*args, **kwargs) 

     skus = product.sku_set.all() 
     self.fields['size'].queryset = Size.objects.filter(sku__in=skus).values('amount', 'unit').distinct()  

    quantity = forms.IntegerField() 

    class Meta: 
     model = Sku 
     fields = ('size',) 

Dies bringt die folgenden Werte in meinem Dropdown-Menü für "Größe":

{'amount':5, 'size':'cups'} 

Wie kann ich es haben einfach zeigen: "5 Tassen"?

Antwort

0

Ich bin nicht sicher, ob ich Ihre Frage vollständig verstanden habe, aber ich kann Ihnen sagen, dass es nicht korrekt ist, .values() zu verwenden, wenn Sie das Abfragefeld des Größenfelds festlegen.

Auch wenn .values() immer noch einen Abfragesatz zurückgibt, handelt es sich nicht mehr um einen Abfragesatz von Modellinstanzen, sondern stattdessen um Wörterbücher. Das wird nicht mit ModelChoiceField fliegen, die Sie als das Formularfeld für size verwenden.

Sie können wahrscheinlich bekommen, was Sie wollen, indem Sie label_from_instance für das Größenfeld ändern.

Schnell Beispiel:

class Size(models.Model): 
    amount = models.IntegerField(default=0) 
    unit = models.CharField(max_length=64) 
    created_at = models.DateTimeField(auto_now_add = True) 
    updated_at = models.DateTimeField(auto_now = True) 

    def __str__(self): 
     return str(self.amount) + ' ' + self.unit + ' size' 

    def custom_label(self): 
     # I assume this would return '5 cups' 
     return '{} {}'.format(self.size, self.unit) 

Dann in Ihrer Form:

class SkuForm(forms.ModelForm): 

    def __init__(self, *args, **kwargs): 
     product = kwargs.pop('product', None) 
     super(SkuForm, self).__init__(*args, **kwargs) 

     self.fields['size'].label_from_instance = lambda obj: obj.custom_label() 


    class Meta: 
     model = Sku 
     fields = ('size',) 
0

Ich holte die queryset ich so wollte:

def __init__(self, *args, **kwargs): 
     self.product = kwargs.pop('product', None) 
     super(SkuForm, self).__init__(*args, **kwargs) 

     skus = self.product.sku_set.all() 

     size_vals = [] 
     size_ids = [] 
     all_sizes = Size.objects.filter(sku__in=skus) 

     for size in all_sizes: 
      key = str(size.amount)+'_'+size.unit 
      if any(key in d for d in size_vals): 
       pass 
      else: 
       size_dict = {} 
       size_dict[key]=size.id 
       size_vals.append(size_dict) 
     for size_val in size_vals: 
      for d in size_val: 
       id = size_val[d] 
       size_ids.append(id) 

self.fields['size'].queryset = Size.objects.filter(id__in=size_ids) 
Verwandte Themen