[Django] Generic View - Doppelte Zeilen im Output entfernen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
orschiro
User
Beiträge: 60
Registriert: Donnerstag 11. Dezember 2008, 16:10
Kontaktdaten:

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
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

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 ;)
orschiro
User
Beiträge: 60
Registriert: Donnerstag 11. Dezember 2008, 16:10
Kontaktdaten:

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?
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

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/).
orschiro
User
Beiträge: 60
Registriert: Donnerstag 11. Dezember 2008, 16:10
Kontaktdaten:

Das hat wunderbar funktioniert. Danke :)
Antworten