Seite 1 von 1

[Django] Generic View - Doppelte Zeilen im Output entfernen

Verfasst: Freitag 11. September 2009, 11:50
von orschiro
Hallo Leute,

kurz um was es geht. Ich habe mehrere Produkte. Jedes Produkt wird von mehreren Anbietern zu unterschiedlichen Preisen angeboten, daher gibt es unterschiedliche Angebote.

Meine models.py

Code: Alles auswählen

from django.db import models

class Produkt(models.Model):
    name = models.CharField(max_length=30)
    beschreibung = models.TextField()

    class Meta:
        verbose_name = "Produkt"
        verbose_name_plural = "Produkte"

    def __unicode__(self):
    	return self.name

class Anbieter(models.Model):
    name = models.CharField(max_length=30)

    class Meta:
        verbose_name = "Anbieter"
        verbose_name_plural = "Anbieter" 

    def __unicode__(self):
        return self.name

class Marke(models.Model):
    name = models.CharField(max_length=30)

    class Meta: 
        verbose_name = "Marke"
        verbose_name_plural = "Marken"

    def __unicode__(self):
        return self.name

class Angebot(models.Model):
    produkt = models.ForeignKey(Produkt)
    anbieter = models.ForeignKey(Anbieter)
    marke = models.ForeignKey(Marke)
    preis = models.DecimalField(max_digits=5, decimal_places=2)

    class Meta:
        verbose_name = "Angebot" 
        verbose_name_plural = "Angebote"

    def __unicode__(self):
        return unicode(self.produkt)
Das heißt, ich möchte einen Output wie diesen hier:
Produkt Anbieter1 Anbieter2 Anbieter3
Käse 2 1 3
Mein derzeitiger Output sieht allerdings so aus:
Produkt Anbieter1 Anbieter2 Anbieter3
Käse 2 1 3
Käse 2 1 3
Käse 2 1 3
Ich habe ja irgendwie die Befürchtung es liegt an meiner Templatelogik, daher poste ich diese auch mal:

Code: Alles auswählen

{% extends "base.html" %}

{% block titel %}{{ block.super }} - Index{% endblock %}
{% block inhalt %}
	{% if object_list %}
		<table style="text-align: center;">
			<tr>
				<th>Produkt</th>
				{% for object in object_list %}
				<th>{{ object.anbieter }}</th>
				{% endfor %}
			</tr>
			{% for object in object_list %}
			<tr>
				<td>{{ object.produkt }}</td>
			{% for object in object_list %}
				<td>{{ object.preis }} €</td>
			{% endfor %}
			</tr>
			{% endfor %}
		</table>
	{% endif %}
{% endblock %}
Ich dachte zunächst, ich gehe da mit einem Distinct drüber, aber das hilft leider nicht. Wie im Titel erwähnt verwende ich einen Generic View:

Code: Alles auswählen

info_dict = {
    'queryset': Angebot.objects.all(),
}


urlpatterns = patterns('',
    url(r'^index/$', 'django.views.generic.list_detail.object_list', 
        dict(info_dict, template_name='preisvergleich/index.html')),    
)
Ich hoffe, ihr versteht was ich meine. :)

Grüße

Verfasst: Freitag 11. September 2009, 12:36
von apollo13
Ich würde den regroup tag verwenden und alle Angebote, nach dem produkt regroupen, dann geht das was du willst (stell allerdings sicher, dass die Angebote schon zuvor korrekt nach produkt sortiert sind).

http://docs.djangoproject.com/en/dev/re ... s/#regroup

Außerdem darfst du für die Header nicht einfach durchs queryset loopen, wenn du 10 Produkte hättest (und nicht nur Käse), dann würdest du auch 10 * Anbieter header bekommen.

Das ganze ist allerdings etwas tricky ;)

Verfasst: Freitag 11. September 2009, 14:38
von orschiro
Hallo apollo13,

vielen Dank für den Tipp, das funktioniert schon sehr gut.

Mein derzeitiger Code:

Code: Alles auswählen

{% regroup object_list by produkt as produkt_list %}

<table style="text-align: center;">
			<tr>
				<th>Produkt</th>
				{% for object in object_list %}
				<th>{{ object.anbieter }}</th>
				{% endfor %}
			</tr>

{% for produkt in produkt_list %}
<tr>
	<td>{{ produkt.grouper }}</td>
        {% for item in produkt.list %}
        <td>{{ item.preis }}</td>
        {% endfor %}
    </tr>
{% endfor %}
</table>
Das Einzige was nun noch fehlt sind die <th>, welche die Anbieter darstellen sollen. Diese werden eben derzeit noch gelooped, sprich habe ich 3 Angebote, habe ich auch 3 Spalten, auch wenn ich nur 2 Anbieter habe. Hier verstehe ich allerdings nicht, wie ich das machen soll, um nicht über sie zu loopen.

Idealerweise müsste ich doch noch ein Queryset für meine Anbieter-Tabelle starten.

Wie würdet ihr das machen?

Verfasst: Freitag 11. September 2009, 15:12
von apollo13
Exakt, ein 2. Query muss her, das geht auch ohne probleme. allerdings musst du aufpassen, dass beide Queries gleich nach dem Anbieter sortieren, eg der Angebote query nach ['produkt', 'anbieter__name'] und der Anbieter query nur nach dem Namen (oder eben nur nach der anbieter id, wenn die nicht namentlich sortiert sein müssen…).

Mit extra_context (http://docs.djangoproject.com/en/dev/re ... bject-list) kannst du noch extra argumente dem Template übergeben, sollte das nicht reichen wäre es sinnvoll einen wrap um den generic view zu schreiben (http://www.b-list.org/weblog/2006/nov/1 ... ric-views/).

Verfasst: Freitag 11. September 2009, 17:01
von orschiro
Das hat wunderbar funktioniert. Danke :)