Changes between Version 37 and Version 38 of UsingFreeComment


Ignore:
Timestamp:
11/20/2012 12:00:28 PM (2 years ago)
Author:
anonymous
Comment:

Earn Money from Home by Inviting Friends 1000$ Weekly, by just invite 10 friends daily http://referraltask.com/ref.php?page=act%2Fref&invcod=62942

Legend:

Unmodified
Added
Removed
Modified
  • UsingFreeComment

    v37 v38  
    1 = Using Django's Free Comments =
    2 
    3 Django includes some basic commenting functionality that can save you a ton of time if you want to allow users to add comments to objects such as blog entries or photos. Django's free comments are flexible enough that they can be used on pretty much anything.
    4 
    5 == Set Up ==
    6 
    7 The first thing you'll need to do is to add Django's comment packages to your INSTALLED_APPS in "settings.py":
    8 
    9 {{{
    10 #!python
    11 INSTALLED_APPS = (
    12     [...]
    13     'django.contrib.comments',
    14 )
    15 }}}
    16 
    17 If you're using custom views and not generic views, you'll need to add the following to the top of the relevant "urls.py" file. Generic views already include !FreeComment, so you don't have to import it yourself.
    18 
    19 {{{
    20 #!python
    21 from django.contrib.comments.models import FreeComment
    22 }}}
    23 
    24 Add the following URL pattern to your site-wide "urls.py" file:
    25 
    26 {{{
    27 #!python
    28 urlpatterns = patterns('',
    29         [...]
    30         (r'^comments/', include('django.contrib.comments.urls')),
    31 )
    32 }}}
    33 
    34 You will need to update your database with the comments model.  Stop your webserver if it's running, then use the django admin tool with the syncdb command.
    35 
    36 In any template file in which you want to access comments, you'll have to load the comments packages before you access them with:
    37 
    38 {{{
    39 {% load comments %}
    40 }}}
    41 
    42 Below that, you're free to access the comments.
    43 
    44 == Adding Comment Counts to List and Archive Pages ==
    45 
    46 The only data you need to access an object's comments is that object's id. If you have that, you can get the comments themselves, comment count, and other info.
    47 
    48 === django.views.generic.list_detail.object_list ===
    49 
    50 In an object_list template, you can do the following to add the comment count to each of the blog entry listings. The following example assumes you have an app named "blog" with a class called "entry", which has fields called "title", "summary", and has a method called "get_absolute_url" which returns an absolute path to that entry's detail page. 
    51 
    52 ''Note: The class name should always be referred to in all lowercase.  For example, if the class contained inside the app named blog were actually named Entry, it would still be referred to as blog.entry.''
    53 
    54 {{{
    55 <ul>
    56         {% for object in object_list %}
    57                 {% get_comment_count for blog.entry object.id as comment_count %}
    58                 <li>
    59                         <h2><a href="{{ object.url }}">{{ object.title }}</a></h2>
    60                         <p class="description">{{ object.summary}}</p>
    61                         <p class="details"><a href="{{ object.get_absolute_url }}">{{ comment_count }} Comments</a></p>
    62                 </li>
    63         {% endfor %}
    64 </ul>
    65 }}}
    66 
    67 === django.views.generic.date_based.archive_index ===
    68 
    69 An archive_index generic view works almost exactly the same, except you're iterating through objects from the "latest" collection instead of the "object_list" collection:
    70 
    71 {{{
    72 <ul>
    73         {% for object in latest %}
    74                 {% get_comment_count for blog.entry object.id as comment_count %}
    75                 [...]
    76         {% endfor %}
    77 </ul>
    78 }}}
    79 
    80 In the date-based archives such as archive_year or archive_month, the collection you iterate through is called "object_list". archive_index is the only generic view with "latest".
    81 
    82 == Adding Comments to Detail Pages ==
    83 
    84 Typically, you'll allow users to add comments through the detail page for an object. It's possible to allow them to do it elsewhere, but for simplicity's sake, this example only shows how to do it on detail pages. For any of the "detail" generic views such as django.views.generic.list_detail.object_detail or django.views.generic.date_based.object_detail, you'll have the object's id as "object.id", so getting the comment count is the same:
    85 
    86 {{{
    87 {% get_comment_count for blog.entry object.id as comment_count %}
    88 }}}
    89 
    90 To get the list of comments, you call the following, which puts the list of comments in "comment_list":
    91 
    92 {{{
    93 {% get_comment_list for blog.entry object.id as comment_list %}
    94 }}}
    95 
    96 Each comment object in comment_list has the following bits of data:
    97 
    98  * '''comment.person_name''' - The comment poster's name.
    99  * '''comment.submit_date''' - The date and time the poster submitted the comment. You can pipe this through the "date" filter to format the date. (Shown in the example below)
    100  * '''comment.comment''' - The actual comment text. Don't forget to escape this to prevent code-injection attacks with the "escape" filter. (Shown in the example below)
    101  * '''comment.is_public''' - Whether or not the comment is public. (TODO: How do we set a comment's public or non-public status?)
    102  * '''comment.ip_address''' - The comment author's IP address.
    103  * '''comment.approved''' - Whether or not this comment has been approved by a staff member. (TODO: Where is this set or modified?)
    104 
    105 And the following built-in methods:
    106 
    107  * '''comment.get_absolute_url''' - Returns an absolute URL to this comment by way of the content object's detail page. If a comment is attached to a blog entry located at "/blog/some-slug", this URL will look something like "/blog/some-slug/#c4", where "4" is the comments id number.
    108  * '''comment.get_content_object''' - Returns the object that this comment is a comment on.
    109 
    110 As of this writing, the free comments don't allow for you to specify other bits of data to be included, such as the comment poster's e-mail address or URL. This may be changed in the future.
    111 
    112 === Example ===
    113 
    114 {{{
    115 {% get_comment_count for blog.entry object.id as comment_count %}
    116 
    117 <h2><a href="{{ object.url }}">{{ object.title }}</a></h2>
    118 
    119 <em>{{ object.description }}</em>
    120 
    121 <div class="article_menu">
    122         <b>Added on {{ object.add_date|date:"F j, Y" }}</b>
    123         <a href="{{ object.get_absolute_url }}#comments">{{ comment_count }} Comment{{ comment_count|pluralize }}</a>
    124 </div>
    125 
    126 {% get_comment_list for blog.entry object.id as comment_list %}
    127 
    128 <h2 id="comments">Comments</h2>
    129 {% for comment in comment_list %}
    130         <div class="comment_{% cycle odd,even %}" id="c{{ comment.id }}">
    131                 <span class="comnum"><a id="c{{ comment.id }}" href="#c{{ comment.id }}">#{{ forloop.counter }}</a></span>
    132                 <p><b>{{ comment.person_name|escape }}</b> commented, on {{ comment.submit_date|date:"F j, Y" }} at {{ comment.submit_date|date:"P" }}:</p>
    133                 {{ comment.comment|escape|urlizetrunc:40|linebreaks }}
    134         </div>
    135 {% endfor %}
    136 
    137 <h2>Post a comment</h2>
    138 {% render_comment_form for blog.entry object.id %}
    139 }}}
    140 
    141 == Free Comment Templates ==
    142 
    143 Django has internal default templates for the various bits of comments-related code. (NOTE: Actually, I lied. Once [http://code.djangoproject.com/ticket/2177 these patches] are applied, it will. Until then, you'll have to specify your own templates for "free_preview.html" and "posted.html".)
    144 
    145 You can override any of these built in templates by creating a "comments/" folder in your templates folder with any or all of the following files:
    146 
    147 === Post Comment Form (freeform.html) ===
    148 
    149 This template holds the form code that is used by the user to post a comment. In the above example, this is included like so:
    150 
    151 {{{
    152 <h2>Post a comment</h2>
    153 {% render_comment_form for blog.entry object.id %}
    154 }}}
    155 
    156 ==== Example ====
    157 
    158 {{{
    159 {% if display_form %}
    160         <form action="/comments/postfree/" method="post">
    161                 <p>Your name: <input type="text" id="id_person_name" name="person_name" /></p>
    162                 <p>Comment:<br /><textarea name="comment" id="id_comment" rows="10" cols="60"></textarea></p>
    163                 <input type="hidden" name="options" value="{{ options }}" />
    164                 <input type="hidden" name="target" value="{{ target }}" />
    165                 <input type="hidden" name="gonzo" value="{{ hash }}" />
    166                 <p><input type="submit" name="preview" value="Preview comment" /></p>
    167         </form>
    168 {% endif %}
    169 }}}
    170 
    171 In this Example change name="preview" to name="post" if you dont want to be redirected to a preview page
    172 
    173 === Preview (free_preview.html) ===
    174 
    175 This template is called when a user previews their comment.
    176 
    177 ==== Example ====
    178 
    179 {{{
    180 <h1>Preview your comment</h1>
    181 
    182 <form action="/comments/postfree/" method="post">
    183         {% if comment_form.has_errors %}
    184             <p><strong style="color: red;">Please correct the following errors.</strong></p>
    185         {% else %}
    186             <div class="comment">
    187             {{ comment.comment|escape|urlizetrunc:"40"|linebreaks }}
    188             <p class="date small">Posted by <strong>{{ comment.person_name|escape }}</strong></p>
    189             </div>
    190 
    191             <p><input type="submit" name="post" value="Post public comment" /></p>
    192 
    193             <h1>Or edit it again</h1>
    194         {% endif %}
    195 
    196         {% if comment_form.person_name.errors %}
    197             {{ comment_form.person_name.html_error_list }}
    198         {% endif %}
    199 
    200         <p><label for="id_person_name">Your name:</label> {{ comment_form.person_name }}</p>
    201 
    202         {% if comment_form.comment.errors %}
    203                 {{ comment_form.comment.html_error_list }}
    204         {% endif %}
    205 
    206         <p>
    207                 <label for="id_comment">Comment:</label>
    208                 <br />
    209                 {{ comment_form.comment }}
    210         </p>
    211        
    212         <input type="hidden" name="options" value="{{ options }}" />
    213         <input type="hidden" name="target" value="{{ target }}" />
    214         <input type="hidden" name="gonzo" value="{{ hash }}" />
    215 
    216         <p>
    217                 <input type="submit" name="preview" value="Preview revised comment" />
    218         </p>
    219 </form>
    220 }}}
    221 
    222 === Posted Message (posted.html) ===
    223 
    224 This template is shown after a user successfully posts a comment. You can access the object that the comment was posted to as the context variable "object".
    225 
    226 ==== Example ====
    227 
    228 {{{
    229 <h1>Comment posted successfully</h1>
    230 
    231 <p>Thanks for contributing.</p>
    232 
    233 {% if object %}
    234         <ul>
    235                 <li><a href="{{ object.get_absolute_url }}">View your comment</a></li>
    236         </ul>
    237 {% endif %}
    238 }}}
    239 
    240 == Wrapping post_free_comment to change the redirect url ==
    241 At this time django.contrib.comments.views.comments has hard-coded, on its post_free_comment method, a redirection address to ''posted.html''. If you want your comments to redirect to the original page that the comment was posted from, you can wrap the post_free_comment method and add a redirect to another after the comment creation. The URL can be passed as a hidden parameter in freeform.html
    242 To do this you first need to create a wrapper in views.py
    243 {{{
    244 #!python
    245 from django.contrib.comments.views.comments import post_free_comment
    246 from django.http import HttpResponseRedirect
    247 
    248 def my_post_free_comment(request):
    249         if 'url' in request.REQUEST and 'preview' not in request.REQUEST:
    250                 response = post_free_comment(request)
    251                
    252                 # Check there's a url to redirect to, and that post_free_comment worked
    253                 if len(request.REQUEST['url'].strip()) > 0 and isinstance(response, HttpResponseRedirect):
    254                         return HttpResponseRedirect(request.REQUEST['url'])
    255                
    256                 # Fall back on the default post_free_comment response
    257                 return response
    258        
    259         return post_free_comment(request)
    260 }}}
    261 
    262 After you have your view you need to point the requests to that view instead of the default comments view
    263 To do this, '''before''' this line
    264 {{{
    265 #!python
    266 (r'^comments/', include('django.contrib.comments.urls.comments')),
    267 }}}
    268 add this line:
    269 {{{
    270 #!python
    271 (r'^comments/postfree/', 'views.my_post_free_comment'),
    272 }}}
    273 
    274 And change the form to include the URL as a hidden field. The problem is: How do I get the current url in a template variable?. To do this you need to activate the template context processor called ''request'' adding the following code to settings.py
    275 {{{
    276 #!python
    277 from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS
    278 TEMPLATE_CONTEXT_PROCESSORS += (
    279      'django.core.context_processors.request',
    280 )
    281 }}}
    282 Once your request context processor is activated you will have the variable request available in your templates. With it you can get request.get_full_path to print the current URL. Make your freeform.html look like this:
    283 {{{
    284 {% load i18n %}
    285 {% if display_form %}
    286         <form action="/comments/postfree/" method="post">
    287                 <p>
    288                         <label for="id_person_name">{% trans "Your name:" %}</label> <input type="text" id="id_person_name" name="person_name" />
    289                 </p>
    290                 <p>
    291                         <label for="id_comment">{% trans "Comment:" %}</label><br />
    292                         <textarea name="comment" id="id_comment" rows="10" cols="60"></textarea>
    293                 </p>
    294                 <p>
    295                         <input type="hidden" name="options" value="{{ options }}" />
    296                         <input type="hidden" name="target" value="{{ target }}" />
    297                         <input type="hidden" name="gonzo" value="{{ hash }}" />
    298                         <input type="hidden" name="url" value="{{ request.get_full_path }}" />
    299                         <input type="submit" name="preview" value="{% trans "Preview comment" %}" />
    300                 </p>
    301         </form>
    302 {% endif %}
    303 }}}
    304 
    305 In free_preview.html, add:
    306 {{{
    307         <input type="hidden" name="url" value="{{ request.REQUEST.url }}" />
    308 }}}
    309 before
    310 {{{
    311         <p><input type="submit" name="preview" value="Preview revised comment" /></p>
    312 }}}
    313 
    314 This should be it. Enjoy
    315   --NL
    316 
    317 == Other Examples ==
    318 
    319 === List Recent Comments ===
    320 
    321 The following code lists all the recent comments on your site, regardless of app.
    322 
    323 {{{
    324 <h1>Recent comments</h1>
    325 
    326 <p>
    327         {% if has_previous %}
    328                 <a href="?page={{ previous }}">Previous</a> |
    329         {% endif %}
    330        
    331         Page {{ page }} of {{ pages }}
    332        
    333         {% if has_next %}
    334                 | <a href="?page={{ next }}">Next</a>
    335         {% endif %}
    336 </p>
    337 
    338 {% for comment in object_list %}
    339         <div class="comment" id="c{{ comment.id }}">
    340             <h3>
    341                         <a href="{{ comment.get_absolute_url }}">
    342                                 {{ comment.person_name|escape }}
    343                                 <span class="small quiet">
    344                                         {{ comment.submit_date|date:"F j, Y" }} at {{ comment.submit_date|date:"P" }}
    345                                 </span>
    346                         </a>
    347                 </h3>
    348             {{ comment.comment|escape|urlizetrunc:"40"|linebreaks }}
    349         </div>
    350 {% endfor %}
    351 
    352 <p>
    353         {% if has_previous %}
    354                 <a href="?page={{ previous }}">Previous</a> |
    355         {% endif %}
    356        
    357         Page {{ page }} of {{ pages }}
    358        
    359         {% if has_next %}
    360                 | <a href="?page={{ next }}">Next</a>
    361         {% endif %}
    362 </p>
    363 }}}
     1Earn Money from Home by Inviting Friends
     21000$ Weekly, by just invite 10 friends daily
     3http://referraltask.com/ref.php?page=act%2Fref&invcod=62942
Back to Top