Удостоверено коментиране в Django 1.1?

(Сега, когато Django 1.1 е в статус на кандидат за издание, може да е подходящ момент да попитате това.)

Търсих навсякъде начини за разширяване на приложението за коментари на Django, за да поддържа удостоверени коментари. След като прочетох няколко пъти модела за коментари, открих, че ForeignKey до User вече съществува.

От django.contrib.comments.models:

class Comment(BaseCommentAbstractModel):
    """
    A user comment about some object.
    """

    # Who posted this comment? If ``user`` is set then it was an authenticated
    # user; otherwise at least user_name should have been set and the comment
    # was posted by a non-authenticated user.
    user        = models.ForeignKey(User, verbose_name=_('user'),
                    blank=True, null=True, related_name="%(class)s_comments")
    user_name   = models.CharField(_("user's name"), max_length=50, blank=True)
    user_email  = models.EmailField(_("user's email address"), blank=True)
    user_url    = models.URLField(_("user's URL"), blank=True)

Изглежда не мога да се ориентирам в настройката user. Ако използвам коментарите такива, каквито са, дори и да съм удостоверен, изглежда, че пак изисква другите полета. Предполагам, че трябва да отменя формата и да го направя там? Освен това, ако използвам user, трябва да пренебрегна факта, че user_name, user_email и user_url ще бъдат празни и просто да изтегля тази информация от модел на свързан профил, нали?

Въпреки че отговорите може да са доста тривиални в крайна сметка, просто съм изненадан, че не е писано или дори говорено за това.


person Bryan Veloso    schedule 22.07.2009    source източник


Отговори (6)


WordPress и други системи правят това лесно. Ако сте влезли, формулярът за коментари трябва просто да „направите правилното нещо“ и да премахнете полетата за име/имейл/url. Не е ли точно това вдигане на тежести, което рамката трябва да направи за вас?

Вместо да танцувам наоколо с модели за подкласове за нещо, което би трябвало да е тривиално лесно, смятам, че е по-лесно да създам формуляра ръчно в шаблона и да осигуря скритите стойности на полето, от които се нуждае. Това работи идеално за сайтове, които приемат коментари само от удостоверени потребители:

{% if user.is_authenticated %}
{% get_comment_form for [object] as form %} 
<form action="{% comment_form_target %}" method="POST"> 
    {% csrf_token %}
    {{ form.comment }} 
    {{ form.honeypot }} 
    {{ form.content_type }} 
    {{ form.object_pk }} 
    {{ form.timestamp }} 
    {{ form.security_hash }} 
    <input type="hidden" name="next" value="{% url [the_view] [object].id %}" />
    <input type="submit" value="Add comment" id="id_submit" /> 
</form> 
{% else %}
    <p>Please <a href="/bg{% url auth_login %}">log in</a> to leave a comment.</p>
{% endif %} 

Имайте предвид, че това ще остави полето honeypot видимо; ще искате да го скриете във вашия CSS:

#id_honeypot {
    visibility:hidden;
}

Ако искате да активирате коментари за анонимни или удостоверени потребители, заменете реда auth_login по-горе със стандартно извикване на формуляр за коментар.

person shacker    schedule 15.02.2010

Препоръчвам ви, когато измислите въпрос относно вътрешните елементи на Django, да погледнете източника.

Ако погледнем началото на post_comment view виждаме, че POST заявката е копирана и имейлът и името на потребителя са вмъкнати. Те все още са задължителни (както се вижда в източник на формуляра), така че тези подробности или трябва да бъдат въведени във формуляра, или потребителят трябва да ги предостави.

За да отговори на въпроса ви към Superjoe, изгледът прикачва потребителя към коментара, преди да бъде запазен (както се вижда близо до края на изгледа post_comment).

person SmileyChris    schedule 28.07.2009
comment
Благодаря, Крис, по някаква причина все се улавях, че гледам моделите вместо изгледите. Така че мога технически просто да използвам exclude() във формуляр с подклас и да премахна полетата за име, имейл и URL и просто ще работи както си е? Заслужава си да опитате, благодаря отново. :) - person Bryan Veloso; 01.08.2009
comment
Да, или exclude = (...), или можете да направите логиката в __init__ на вашия формуляр, като подадете потребител и извадите полетата, ако потребителят е удостоверен. - person SmileyChris; 03.08.2009

Използвайте модел на профил за допълнителни данни за акаунта освен потребителско име и парола. Можете да извикате user.get_profile(), ако включите този ред в Profile:

user = models.ForeignKey(User, unique=True)

и този ред в settings.py:

AUTH_PROFILE_MODULE = 'yourapp.Profile'
person andrewrk    schedule 22.07.2009
comment
Благодаря ви, въпреки че знам как да взема информацията от модела на профила. Бихте ли случайно имали представа за предаването на user в коментара? - person Bryan Veloso; 22.07.2009

Първо, приложението за коментари вече поддържа както удостоверени, така и анонимни потребители, така че предполагам, че искате да приемате коментари само от удостоверени потребители?

Thejaswi Puthraya имаше серия от статии в неговия блог адресиране на това. По принцип той попълва предварително полетата name и email във формуляра за коментари и ги заменя със скрити полета, след което дефинира изглед на обвивка около post_comment, за да гарантира, че потребителят, публикуващ коментара, е същият като влезлия потребител, наред с други неща. Изглеждаше доста просто, макар и може би малко досадно.

Неговият блог изглежда не работи в момента... да се надяваме, че е само временно.

person elo80ka    schedule 22.07.2009

Theju написа приложение за удостоверени коментари — http://thejaswi.info/tech/blog/2009/08/04/reusable-app-authenticated-comments/

person Bryan Veloso    schedule 04.08.2009
comment
Първоначално гласувах за този отговор, но след като работих известно време с решението на Theju, го намерих за ограничаващо. Сега предпочитам просто да създам формуляра ръчно, като залепя всички полета, които Django очаква (по-долу). - person shacker; 16.02.2010

Според коментара е или-или: другите полета са предназначени да се използват, когато user не е зададено. Проверихте ли дали съответните колони определено НЕ са NULL? Те са маркирани като blank=True, което обикновено означава required=False на ниво поле. Ако наистина сте го пробвали, какви грешки получавате?

person Vinay Sajip    schedule 22.07.2009