[Django] Newsscript - News nach ID Sortieren

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

[Django] Newsscript - News nach ID Sortieren

Beitragvon EnTeQuAk » Dienstag 2. Januar 2007, 15:05

Hallo! :)

Ich bin grad dabei, n bissl mit Django rumzuspielen... So... Nun habe ich nen kleines Newsscript gebastelt, welches soweit auch gut funktioniert.

Ich habe mir nun ein paar Testnews angelegt, deren Inhalt sieht wiefolgt aus:

Code: Alles auswählen

[{'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!', 'date': datetime.date(2007, 1, 2), 'content': 'TESTNEWS!', 'id': 1L, 'author': 'EnTeQuAk'}, {'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!', 'date': datetime.date(2007, 1, 2), 'content': 'TESTNEWS!!!!!!!!!!!!!!!!!!', 'id': 2L, 'author': 'EnTeQuAk --- TESTAUTHOR!'}, {'headline': 'Neue Test News', 'date': datetime.date(2007, 1, 2), 'content': 'Und? :::) was sagt Ihr dazu?', 'id': 3L, 'author': 'EnTeQuAk'}]


Der Code dazu schaut so aus:

Code: Alles auswählen

def index(request):
    news = News.objects.all().values()

    headlines = []

    for i in news:
        i['content'] = i['content'].replace('\r\n', '\n')
        i['content'] = i['content'].replace('\n', '<br />')

    T = get_template('index.html')
    vars = {
            'test_data': news
    }
    output = T.render(Context(vars))
    return HttpResponse(output)


Und nun sitze ich daran, wie ich die News nun von der höchsten ID (ATM '' 3 '') zur niedrigsten ID sortieren kann, damit ich immer der aktualität anzeigen kann.

Wie kann ich das machen?

MfG EnTeQuAk
BlackJack

Beitragvon BlackJack » Dienstag 2. Januar 2007, 16:38

Beim sortieren eine Funktion angeben die den Schlüssel zum sortieren "berechnet", also den Inhalt von 'id' und das `reverse`-Argument:

Code: Alles auswählen

In [37]: a
Out[37]:
[{'author': 'EnTeQuAk',
  'content': 'TESTNEWS!',
  'date': datetime.date(2007, 1, 2),
  'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!',
  'id': 1L},
 {'author': 'EnTeQuAk --- TESTAUTHOR!',
  'content': 'TESTNEWS!!!!!!!!!!!!!!!!!!',
  'date': datetime.date(2007, 1, 2),
  'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!',
  'id': 2L},
 {'author': 'EnTeQuAk',
  'content': 'Und? :::) was sagt Ihr dazu?',
  'date': datetime.date(2007, 1, 2),
  'headline': 'Neue Test News',
  'id': 3L}]

In [38]: a.sort(key=operator.itemgetter('id'), reverse=True)

In [39]: a
Out[39]:
[{'author': 'EnTeQuAk',
  'content': 'Und? :::) was sagt Ihr dazu?',
  'date': datetime.date(2007, 1, 2),
  'headline': 'Neue Test News',
  'id': 3L},
 {'author': 'EnTeQuAk --- TESTAUTHOR!',
  'content': 'TESTNEWS!!!!!!!!!!!!!!!!!!',
  'date': datetime.date(2007, 1, 2),
  'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!',
  'id': 2L},
 {'author': 'EnTeQuAk',
  'content': 'TESTNEWS!',
  'date': datetime.date(2007, 1, 2),
  'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!',
  'id': 1L}]
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Beitragvon EnTeQuAk » Dienstag 2. Januar 2007, 16:46

Hey Danke! --> Funktioniert! :D
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Beitragvon Y0Gi » Dienstag 2. Januar 2007, 17:22

Alternativ kann man auch eine anonyme Funktion verwenden:

Code: Alles auswählen

a.sort(key=lambda x: x.id, reverse=True)
BlackJack

Beitragvon BlackJack » Dienstag 2. Januar 2007, 17:41

Y0Gi hat geschrieben:Alternativ kann man auch eine anonyme Funktion verwenden:

Code: Alles auswählen

a.sort(key=lambda x: x.id, reverse=True)


Korrektur:

Code: Alles auswählen

a.sort(key=lambda x: x['id'], reverse=True)
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Beitragvon EnTeQuAk » Dienstag 2. Januar 2007, 17:52

Hmm bei letzzterem kommt bei mir immer '' None '' raus...

Code: Alles auswählen

def index(request):
    news = News.objects.all()

    headlines = []

    for i in news.values():
        i['content'] = i['content'].replace('\r\n', '\n')
        i['content'] = i['content'].replace('\n', '<br />')
       
    ### HIER
    news = list(news).sort(key=lambda x: x['id'], reverse=True)
    ### HIER ENDE


    T = get_template('index.html')
    vars = {
            'test_data': news
    }
    output = T.render(Context(vars))
    return HttpResponse(output)


Hab ich irgentetwas falsch verstanden? :)

MfG EnTeQuAk
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Beitragvon Y0Gi » Dienstag 2. Januar 2007, 18:14

Danke BlackJack, war irgendwie auf ein Objektattribut gekommen, aber ist ja ein Dictionary.

EnTeQuAk: list.sort() sortiert eine Liste "in place", d.h. verändert die Liste, auf der es aufgerufen wird und gibt nichts zurück. Entweder (vorzuziehen) verwendest du die somit sortierte Liste weiter oder du benutzt das mit Py2.4(?) eingeführte sorted(), dass zunächst eine Kopie der Liste erstellt, sortiert und dann zurückgibt.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Beitragvon EnTeQuAk » Dienstag 2. Januar 2007, 18:43

Komisch... in der iPython Sitzung gehts:

Code: Alles auswählen

In [13]: liste.sort(key=lambda x: x['id'], reverse=True)

In [14]: liste
Out[14]:
[{'author': 'EnTeQuAk',
  'content': 'Und? :::) was sagt Ihr dazu?',
  'date': datetime.date(2007, 1, 2),
  'headline': 'Neue Test News',
  'id': 3L},
 {'author': 'EnTeQuAk --- TESTAUTHOR!',
  'content': 'TESTNEWS!!!!!!!!!!!!!!!!!!',
  'date': datetime.date(2007, 1, 2),
  'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!',
  'id': 2L},
 {'author': 'EnTeQuAk',
  'content': 'TESTNEWS!',
  'date': datetime.date(2007, 1, 2),
  'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!',
  'id': 1L}]


Aber dann, wenn ichs wiefolgt anwende, so, wies eigentlich funktionieren sollte:

Code: Alles auswählen

def index(request):
    news = News.objects.all().values()

    headlines = []

    for i in news:
        i['content'] = i['content'].replace('\r\n', '\n')
        i['content'] = i['content'].replace('\n', '<br />')

    ### HIER
    list(news).sort(key=lambda x: x['id'], reverse=True)
    ### HIER ENDE


    T = get_template('index.html')
    vars = {
            'test_data': news
    }
    output = T.render(Context(vars))
    return HttpResponse(output)

Bekomme ich folgende Output im Browser:

Code: Alles auswählen

[{'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!', 'date': datetime.date(2007, 1, 2), 'content': 'TESTNEWS!', 'id': 1L, 'author': 'EnTeQuAk'}, {'headline': 'TEST NEWS EINFACH ZUM ANFASSEN!', 'date': datetime.date(2007, 1, 2), 'content': 'TESTNEWS!!!!!!!!!!!!!!!!!!', 'id': 2L, 'author': 'EnTeQuAk --- TESTAUTHOR!'}, {'headline': 'Neue Test News', 'date': datetime.date(2007, 1, 2), 'content': 'Und? :::) was sagt Ihr dazu?', 'id': 3L, 'author': 'EnTeQuAk'}]


Woran kann das denn nun liegen?

MfG EnTeQuAk

EDIT:

und beim Versuch mit '' sorted() '' bekomme ich einen '' TypeError '' , was ich noch verstehen kann... aber wie muss ich das umwandeln? -- das will net so richtig klappen :'(

Code: Alles auswählen

Traceback (most recent call last):
File "/usr/lib/python2.4/site-packages/django/core/handlers/base.py" in get_response
  77. response = callback(request, *callback_args, **callback_kwargs)
File "/home/ente/entes_world/../entes_world/portal/views.py" in index
  14. i['content'] = i['content'].replace('\r\n', '\n')

  TypeError at /
  unsubscriptable object
BlackJack

Beitragvon BlackJack » Dienstag 2. Januar 2007, 19:44

EnTeQuAk hat geschrieben:Komisch... in der iPython Sitzung gehts:


Da hast Du ja auch die Liste die Du sortiert hast ausgegeben...

Code: Alles auswählen

def index(request):
    news = News.objects.all().values()

    # ...

    ### HIER
    list(news).sort(key=lambda x: x['id'], reverse=True)
    ### HIER ENDE


Hier erzeugst Du eine *neue* Liste mit Referenzen auf die Objekte in `news`. Und diese Liste sortierst Du. Und dann schlägt der Garbage Collector zu, weil diese Liste weder über einen Namen, noch eine Referenz von woanders her erreichbar ist.

Code: Alles auswählen

    T = get_template('index.html')
    vars = {
            'test_data': news
    }


Und hier verwendest Du `news`, an dem sich natürlich überhaupt nichts geändert hat.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 2. Januar 2007, 20:46

Was spricht eigentlich gegen den Einsatz von order_by?

Und übrigens geht Templates rendern mit return_to_response wesentlich schneller und kürzer.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Beitragvon EnTeQuAk » Dienstag 2. Januar 2007, 21:42

Ohh :) LoL :D

Da habe ich doch glatt das Minuszeichen übersehen.

Dankeschön Leonidas!

Danke aber auch an die andere, die hier geholfen haben.
Hat im Enddefekt alles geklappt, nur halt ein einfaches '' order_by '' ist doch wesentlich kürzer :D

MfG EnTeQuAk

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]