Blog w Django II - Komentarze
14 July 2008
Comments
Zajmiemy się teraz rozbudową "bloga" zarysowanego we wprowadzającym do django artykule. Obecnie nasza aplikacja listuje wiadomości na stronie głównej wraz z ich stronicowaniem. Teraz dorobimy widok dla danej wiadomości pozwalający na czytanie i dodawanie komentarzy. Źródła do pobrania na końcu artykułu.Zaczniemy od stworzenia modelu komentarzy (możemy użyć systemu komentarzy z Django, ale dla celów edukacyjnych stworzymy własny system). Do /blog/news/models.py dodaj:
class NewsComments(models.Model):
news = models.ForeignKey(News)
text = models.TextField(verbose_name='Treść')
author = models.CharField(max_length=255, verbose_name='Autor', blank=True)
news = models.ForeignKey(News)
Oprócz tego pole na tekst i autora komentarza. Tworzymy tabelę w bazie danych wydając polecenie:
python manage.py syncdb
Teraz zajmijmy się widokiem dane newsa. Każdy news ma pole ID o unikalnej wartości, tak więc załóżmy że wykorzystamy url w postaci /news/ID/ do wyświetlenie wiadomości o podanym ID. W urls.py dodajemy regułę:
(r'^news/(?P<id>[0-9]+)/$', 'news.views.show_news'),
from django.shortcuts import render_to_response
from blog.news.models import *
def show_news(request, id):
news = News.objects.get(id=id)
return render_to_response('show.html', {'news':news})
{% extends "index.html" %}
{% block content %}
<h3>{{ news.title }}</h3>
<p>{{ news.text }}... {{ news.date|date:"d.m.Y" }}</p>
{% endblock %}
| <b><a href="/news/{{ new.id }}/">Komentarze</a></b>: XYZ
Kolejny etap to formularz dodawania komentarzy na szczegółowym widoku wiadomości. Wykorzystamy standardowy manipulator dodawania wpisu. Edytujemy widok w /blog/news/views.py do postaci:
# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from blog.news.models import *
from django import oldforms as forms
from django.http import HttpResponseRedirect
def show_news(request, id):
news = News.objects.get(id=id)
# tworzymy manipulator
manipulator = NewsComments.AddManipulator()
if request.POST:
# formularz wysłany
data = request.POST.copy()
# dodajemy brakujące dane
data['author'] = str(request.user)
data['news'] = id
errors = manipulator.get_validation_errors(data)
# jeżeli nie ma błędów zapisz dane i odświerz stronę - przekieruj na ten sam url
if not errors:
new = manipulator.save(data)
return HttpResponseRedirect('/news/'+ str(id) +'/')
else:
# formularz nie wysłany
errors = {}
data = {}
# formularz
form = forms.FormWrapper(manipulator, data, errors)
return render_to_response('show.html', {'news':news, 'form':form})
{% extends "index.html" %}
{% block content %}
<h3>{{ news.title }}</h3>
<p>{{ news.text }}... {{ news.date|date:"d.m.Y" }}</p>
<br /><br />
<h3>Dodaj Komentarz</h3>
<form method="post" action=".">
{{ form.text }}{% if form.text.errors %}<br />*** {{ form.text.errors|join:", " }}{% endif %}<br />
<input type="submit" value="Dodaj Komentarz" />
</form>
{% endblock %}
errors = manipulator.get_validation_errors(data)
Dopisaliśmy brakujące dane do słownika data. W przypadku dodania komentarza strona zostanie odświeżona (przekierowanie na ten sam URL). Efekt:
Teraz dodamy listę komentarzy dla danej wiadomości nad formularzem ich dodawania. W widoku dojdzie jedna linijka i zmieni się wiersz z render_to_response:
comments = NewsComments.objects.filter(news=id)
return render_to_response('show.html', {'news':news, 'form':form, 'comments':comments})
{% extends "index.html" %}
{% block content %}
<h3>{{ news.title }}</h3>
<p>{{ news.text }}... {{ news.date|date:"d.m.Y" }}</p>
<br />
{% for c in comments %}
<b>{{ c.author }} napisał:</b><br />
{{ c.text }}<br /><br />
{% endfor %}
<br /><br />
<h3>Dodaj Komentarz</h3>
<form method="post" action=".">
{{ form.text }}{% if form.text.errors %}<br />*** {{ form.text.errors|join:", " }}{% endif %}<br />
<input type="submit" value="Dodaj Komentarz" />
</form>
{% endblock %}
Zanim zajmiemy się ważnymi wykończeniami systemu komentarzy dodamy liczniki komentarzy w list.html. Zamiast "XYZ" wystarczy wstawić {{ new.newscomments_set.count }} i gotowe. Zastosowaliśmy szablonową wersję dostępu do danych z powiązanej tabeli (bez nawiasów po "count"). Teraz wykończmy komentarze. Problem jaki musimy rozwiązać to tagi HTML w komentarza, których obecny kod nie filtruje. By rozwiązać problem wystarczy że zastosujemy jeden z dostępnych filtrów - escape:
{% for c in comments %}
<b>{{ c.author }} napisał:</b><br />
{{ c.text|escape }}<br /><br />
{% endfor %}
Źródła
Pobierz źródłaPo rozpakowaniu edytuj ścieżkę w urls.py a następnie stwórz tabele i superadmina.
RkBlog
Comment article