2015-10-15 67 views
1

我是初學者。 我試圖訪問ProductDetailView的模板層中的模型Product的相關項目。我如何檢索Product的'Brand'BrandImagesImageField?我必須穿過一個正向和一個反向ForeignKeydjango模板中的外部方法訪問

編輯,包括get_logo_url

什麼是錯的get_logo_url功能?

產品/ models.py

class Product(models.Model): 

    brand = TreeForeignKey('Brand', verbose_name='parent category', related_name='products', default='') 
    title = models.CharField(max_length=120) 
    description = models.TextField(max_length=500, blank=True, null=True) 
    price = models.DecimalField(decimal_places=2, max_digits=20) 
    active = models.BooleanField(default=True) 
    category = TreeForeignKey('Category', verbose_name='parent category', related_name='products', default='') 
    slug = models.SlugField(default='') 

    objects = ProductManager() 

    class Meta: 
      unique_together = ('slug', 'category') 

    def get_absolute_url(self): 
     return reverse("product_detail", kwargs={"pk":self.pk}) 

    def __unicode__(self): 
     return self.title 

    def get_image_url(self): 
     img = self.productimage_set.first() 
     if img: 
      return img.image.url 
     return img 

品牌/ models.py

def image_upload_to(instance, filename): 
    title = instance.brand.title 
    slug = slugify(title) 
    file_extension = filename.split(".")[1] 
    new_filename = "%s.%s" % (instance.id, file_extension) 
    return "products/%s/%s" % (slug, new_filename) 

class BrandImage(models.Model): 

    brand = models.ForeignKey('Brand', related_name='brandimages') 
    is_slider = models.BooleanField(default=False) 
    is_featured = models.BooleanField(default=False) 
    is_logo = models.BooleanField(default=False) 
    image = models.ImageField(upload_to=image_upload_to) 

    def __unicode__(self): 
     return self.brand.title 

    def get_logo_url(self): 
     if is_logo: 
     img = self.brandimage_set.first() 
     if img: 
      return img.image.url 
     return img 

    def thumb(self): 
     if self.image: 
      return u'<img src="%s" width=120 height=120 />' % (self.image.url) 
     else: 
      return u'No image file found' 
    thumb.allow_tags = True 

class Brand(MPTTModel): 

    title = models.CharField(max_length=50, default='') 
    parent = TreeForeignKey('self', null=True, blank=True, verbose_name='parent brand', related_name='brands') 
    slug = models.SlugField(unique=True) 

    def get_absolute_url(self): 
      return reverse('brands', kwargs={'path': self.get_path()}) 

    def __unicode__(self): 
     return self.title 

模板

<div class="rightpart"> 
    <div class="prodbrand h2"> 
     <h1>{{ product.brand }}</h1>   
     <div class="brandlogo"> 
      {% for image in product.brand.brandimages.all %} 
       <img src="{{image.get_logo_url }}"/> 
      {% endfor %} 
     </div> 
    </div> 
    <div class="prodtitle"><h2>{{ product.title }}</h2> 
</div> 

views.py

class ProductDetailView(DetailView): 
    model = Product 
    template_name = 'products/product.html' 

    def get_context_data(self , *args , **kwargs): 
     context = super(ProductDetailView , self).get_context_data(*args,**kwargs) 
     instance = self.get_object() 
     context["related"] = Product.objects.get_related(instance) 
     return context 

urls.py

url(r'^$', ProductDetailView.as_view(), name='products'), 

有訪問這樣的Django模板洋田的方法嗎?

+0

我猜洋田可在模板中使用簡單,就像其他領域。如果不是,您可以將品牌形象對象與其他字段一起傳遞到上下文中。 –

+0

您想從哪裏訪問它,即:您在模板中加載了哪個對象? –

+0

多數民衆贊成在我想知道...如何加載對象在這裏? –

回答

2

當你使用的是ListView來展示你的產品有幾件事情需要注意:

  • get_context_data()必須返回一個字典:return context缺少
  • super().get_context_data應該*args,**kwargs櫃面你決定要繼承被稱爲在稍後的時間點ProductListView
  • super().get_context_data將包含一個object_list鍵,其中包含由get_queryset()返回的對象列表,其類別爲Product

從模板訪問屬性時,如果django可調用,它將嘗試在沒有參數的情況下調用它。這往往很有用。比如:爲{{ request.user.is_authenticated }}product.brand.brandimages.all

您的模板應該是這樣的:

product_list.html

{% for product in object_list %} 
    <div class="rightpart"> 
     <div class="prodbrand h2"> 
      <h1>{{ product.brand }}</h1>  
      <div class="brandlogo">  
       {% for image in product.brand.brandimages.all %} 
        <img src="{{image.image.url}}"/> 
       {% endfor %} 
      </div><!-- End brandlogos --> 
     </div><!-- End prodbrand --> 
     <div class="prodtitle"> 
      <h2>{{ product.title }}</h2> 
     </div> 
    </div><!-- End rightpart --> 
{% endfor %} 

考慮到,這將招致多個數據庫查詢從模板。您通常希望避免表示層到達數據庫的情況,這就是爲什麼您應該更喜歡在相應的View中執行數據庫查找的原因。此外,對於財產訪問考慮適當使用select_relatedprefetch_related以避免不必要的數據庫查詢。

views.py

class ProductListView(ListView): 

    model = Product 
    queryset = Product.objects.all().active() 

    def get_context_data(self, *args, **kwargs): 
     context = super(ProductListView, self).get_context_data(*args, **kwargs) 
     context["now"] = timezone.now() 
     return context 

    def get_queryset(self, *args, **kwargs): 
     # We call super() for potential subclasses 
     queryset = super(ProductListView, self).get_context_data(*args, **kwargs) 
     queryset.prefetch_related('brand__brandimages') 
     return queryset 
+0

不會** product.brand.brandimages.all **工作??因爲我需要顯示該特定產品的品牌。 –

+0

編輯包含模板...我有一組圖像在品牌中...我如何使用該設置中的第一個圖像? –

+0

編輯包括視圖....使用產品列表視圖 –