latest news

2008-11-09 19:33:42

Umstellung und Migration

2 Comments

unanswered questions

2008-10-30 13:34:21

Syndication Feed-Problem

0 Replies

2008-11-17 16:49:19

dynamische urlpatterns...

2 Replies

2008-12-22 02:46:20

Fragen zu pagination ~~

1 Replies

Board » Django das Framework » Probleme & Fragen » Comments bei einem Blog [erledigt]

Page: 1 2 Next

Tach zusammen,

habe Probleme mich mit Django einzuarbeiten. Das Grundmodel habe ich verstanden, nur fehlen mir einfach noch
Teile um ein funktionsfähiges Kommentar System zu erstellen. Habe mir das Tutorial durchgelesen. Nur steige ich einfach nicht durch,
wie ich jetzt einen POST abfangen, prüfen und speichern kann. Das Tutorial ist an genau dieser Stelle zu kompliziert für einen
Django Anfänger. Der Blog, also Liste und Detail Ansicht funktioniert. Habe in der detail Ansicht eine FORM eingebaut. Ich
verstehe nur diese eine Kleinigkeit nicht, wie ziehe ich die Daten aus dem Kommentar POST.

was ich bisher verstanden habe:

def post(request, post_id):
p = get_object_or_404(BlogEntry, pk=post_id)

und nu folgt irgendwie nen save() oder ?

Das Model für die Comments besteht schon. Auf Generic View möchte ich erst einmal verzichten.
Hast Du den schon eine URL gemappt in der urls.py für das Schicken der Kommentare?
Ich meine die post()-Methode liest sich eigentlich eher so, als ob das die Detail-Ansicht für den Post wäre...

Post am besten mal Deine urls.py
models.py

from django.db import models

class Category(models.Model):
name = models.CharField(maxlength=100)
slug = models.SlugField(unique=True,prepopulate_from=('name',))

def __str__(self):
return self.name

class Meta:
verbose_name_plural = "Categories"

class Admin:
pass

class BlogEntry(models.Model):
title = models.CharField(maxlength=100)
slug = models.SlugField(unique=True,prepopulate_from=('title',))
date = models.DateTimeField(default=models.LazyDate())
precis = models.TextField(blank=True)
content = models.TextField(blank=True)

categories = models.ManyToManyField(Category,related_name='entries',filter_interface=models.HORIZONTAL)

def __str__(self):
return self.title

class Meta:
verbose_name_plural = "Blog entries"

class Admin:
pass

class Comment(models.Model):
name = models.CharField("Name",maxlength=200)
email = models.CharField("Email-Adresse",maxlength=200)
url = models.CharField("Homepage",maxlength=200,blank=True)
text = models.TextField("Kommentar")
pub_date = models.DateTimeField("Datum",'date published')
post = models.ForeignKey(BlogEntry,related_name='comments')

class Meta:
ordering = ['-pub_date']
verbose_name = "Kommentar"
verbose_name_plural = "Kommentare"



urls.py

from django.conf.urls.defaults import *

urlpatterns = patterns('',
(r'^$',"blog.views.summary"),
(r&#039;^(?P<entry_slug>- A-Za-z0-9+)/$&#039;,"blog.views.detail"),
(r&#039;^(?P<entry_slug>- A-Za-z0-9+)/post/$&#039;,"blog.views.postcomment"),
)

views.py

import django.http as http
import django.shortcuts as shortcuts

import models

def summary(request):

entries = models.BlogEntry.objects.order_by(&#039;-date&#039;)

return shortcuts.render_to_response("blog/summary.html",dict(entries=entries))

def detail(request, entry_slug):

entry = shortcuts.get_object_or_404(models.BlogEntry, slug=entry_slug)

return shortcuts.render_to_response("blog/detail.html",dict(entry=entry))

def postcomment(request, entry_slug):

Was muss hier hinein ???



Wie du vielleicht siehst, habe ich den Berreich Comment von deinem Blog kopiert.
Nur weiß ich jetzt halt nicht wie genau die def postcomment() aussehen muss.

Gruß,
Sascha
Also bei mir hab ich das folgenderma&#223;en gemacht, in der views.py:
def foo(request)
	if request.method == &#039;POST&#039;:
		form = CommentForm(request.POST)
		if request.POST[&#039;captcha&#039;] == request.session.get(&#039;captcha&#039;, &#039;&#039;):
			form.captcha_error = False
			if form.is_valid():
				form_data = form.data
				comment = Comment()
				comment.subject = form_data[&#039;subject&#039;]
				comment.name = form_data[&#039;name&#039;]
				comment.homepage = form_data[&#039;homepage&#039;]
				comment.email = form_data[&#039;email&#039;]
				comment.message = form_data[&#039;message&#039;]
				comment.blogentry_id = blogentry.id
				comment.remote_address = "127.0.0.1"
				comment.save()
				form = CommentForm()


Les Dir mal die Doku zu den Newforms durch: http://www.djangoproject.com/documentation/newforms/

Hast Du auch ein Formular in detail.html Template?

Gru&#223;
Jan
Irgendwie komme ich gar nicht mehr weiter (seit drei Tagen versuche ich ein ganz simples comment system zu basteln) . Habe mir deinen Code angesehen, es geht dort um die newforms libary, oder? Das scheint wieder ein ganz anderer Ansatz zu sein eine form zu generieren und zu validieren.
Vielleicht mache ich einfach mal nen Tag pause, klapp momentan einfach nix.
Also bei mir hab ich das folgendermaßen gemacht, in der views.py:
def foo(request)
	if request.method == &#039;POST&#039;:
		form = CommentForm(request.POST)
		if request.POST[&#039;captcha&#039;] == request.session.get(&#039;captcha&#039;, &#039;&#039;):
			form.captcha_error = False
			if form.is_valid():
				form_data = form.data
				comment = Comment()
				comment.subject = form_data[&#039;subject&#039;]
				comment.name = form_data[&#039;name&#039;]
				comment.homepage = form_data[&#039;homepage&#039;]
				comment.email = form_data[&#039;email&#039;]
				comment.message = form_data[&#039;message&#039;]
				comment.blogentry_id = blogentry.id
				comment.remote_address = "127.0.0.1"
				comment.save()
				form = CommentForm()
Das solltest du eigentlich auch kürzer schreiben können, wenn du form_for_model() oder form_for_instance() verwendest, anstatt CommentForm selber zu definieren:

def foo(request)
        if in_edit_mode: CommentForm = form_for_instance(existierender_comment)
        else: CommentForm = form_for_model(Comment)
        ....
	if request.method == &#039;POST&#039;:
		form = CommentForm(request.POST)
		if request.POST[&#039;captcha&#039;] == request.session.get(&#039;captcha&#039;, &#039;&#039;):
			form.captcha_error = False
			if form.is_valid():
				comment = form.save()

Nur weiß ich jetzt halt nicht wie genau die def postcomment() aussehen muss.
Du hast irgendwo einen View, der das Formular als HTML ausgibt. Das Formular ruft beim Abschicken dann die Seite auf, die angegeben ist, und übergibt die Daten per POST.

<form action="ziel-url">


Hinter dieser URL muss dann ein Django-View stehen der die POST Daten ausliest und den Kommentar abspeichert. Das kann auch derselbe sein, der das Formular angezeigt hat. Je nach dem wie man es also implementiert brauchst du entweder zwei Views (einem zum Anzeigen, einen als Abschicken-Ziel), oder nur einen. In letzterem Fall kannst du mit

if request.method == &#039;POST&#039;:
    # abgeschickt
else:
    # formular anzeigen


unterscheiden. Am Ende musst du die Formulardaten in eine Instanz deines Comment-Models übertragen. Ich glaube die besten Beispiele findet man in Blogs, zum Beispiel:

http://weblog.bignerdranch.com/?p=31

Angenommen, man verwendet nur einen view zum Kommentar-anzeigen und Abschicken (bei einem Blog könnte das z.b. der artikel_detail view sein, der den Blogartikel inklusive Kommentarfeld anzeigt.

def artikel_detail(request, artikel_id):
        # informationen zum blog artikel holen
        artikel = BlogEntry.objects.get(pk=artikel_id)
        ..... 

        # kommentarform vorbereiten
        CommentFormClass = forms.form_for_model(CommentModel)  

        # im post mode das abgeschickte auswerten
        if request.POST:
                form = CommentFormClass(request.POST)       
                # auf gültigkeit prüfen. wenn die form ungültig ist (z.b. feld fehlt), dann wird als nächte
                # anweisung render_to_response() mit der geprüften, ungültigen form (die dann, mit dem 
                # richtigen template, automatisch die fehler markieren würde - weil sie weiß dass sie
                # geprüft wurde und was schief ging).
                if form.is_valid(): 
                        # comment enthält jetzt die Instanz des CommentModel                        
                        comment = form.save()                  
                        # Alternative zum vorherigen, um zum beispiel den autor automatisch zu setzen
                        comment = form.save(commit=False)                                                                     
                        comment.author = request.user
                        comment.save()
                        # zum aktuellen artikel "zurück-weiterleiten". das sorgt dafür dass wir a) wieder mit einer 
                        # leeren form starten, und b) der benutzer nicht mit f5 den kommentar aus versehen
                        # dupliziert (weil die POST daten dann weg sind). die url würde in dem fall eigentlich die gleiche
                        # bleiben.
                        return HttpResponseRedirect(&#039;blog_artikel_url&#039;)

        # ohne POST einfach eine leere form anzeigen, die der user verwenden kann
        else:
                form = CommentFormClass()                   

        # ausgeben
        return render_to_response(&#039;Add_Item.html&#039;, {&#039;form&#039;: form, &#039;artikel&#039;: artikel, ...})



Übrigens hat Django ja auch eine Comment-App, allerdings habe ich die nie verwendet.
Das solltest du eigentlich auch kürzer schreiben können, wenn du form_for_model() oder form_for_instance() verwendest, anstatt CommentForm selber zu definieren:

....


Ja stimmt, danke für den Tipp, ich werde meinen Code abändern. :)

Gruß
Jan
Danke für eure schnelle Unterstützung !!! ;D

Habe nun endlich den Zusammen hang zwischen den models und den forms verstanden und konnte es dann umsetzten.
Nun werden in meinem Testblog die comments eingetragen. Die Ausgabe kommt als nächstes.

Damit funzt es....

def detail(request, entry_slug):

   entry = shortcuts.get_object_or_404(models.BlogEntry, slug=entry_slug)

   CommentFormClass = forms.form_for_model(Comment)

   if request.POST:

      form = CommentFormClass(request.POST)

      if form.is_valid():

            form.save()

            return HttpResponseRedirect(&#039;/blog/%s/&#039; % entry_slug)

   else:

      form = CommentFormClass()

   return shortcuts.render_to_response("blog/detail.html",dict(entry=entry),{&#039;form&#039;: form})


Ich nutze folgende Comment Klasse:

class Comment(models.Model):
name = models.CharField("Name",maxlength=200)
email = models.CharField("Email-Adresse",maxlength=200)
url = models.CharField("Homepage",maxlength=200,blank=True)
text = models.TextField("Kommentar")
pub_date = models.DateTimeField("Datum",&#039;date published&#039;)
post = models.ForeignKey(BlogEntry,related_name=&#039;comments&#039;)


Angezeigt wird mir jedoch eine komplette Form, also auch die Möglichkeit den "post" zu wählen.
Das Kommentar sollte schon automatisch dem richtigen post zugeordnet werden, und nicht beim
schreiben auswählbar sein.

thx,
sascha

Page: 1 2 Next