You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You can [browse this repository on GitHub](https://github.com/GitauHarrison/user-comment-moderation-in-flask) to see the code for this tutorial.
7
+
You can browse the source code on [this repository on GitHub](https://github.com/GitauHarrison/user-comment-moderation-in-flask).
8
8
9
9
## Create A Simple Flask Application
10
10
@@ -24,7 +24,7 @@ As our application grows, certain configurations will be needed. At the moment,
24
24
25
25
If you look carefully, I have a module called `config` in the top-level directory. Following the principle of _separtion of concerns_, all the configurations that our application will need will be added here.
With the variable set, we can now update our application instance to read and apply our configurations.
61
61
62
-
`__init__.py: Regiser the config module in application instance`
62
+
`__init__.py`: Regiser the config module in application instance
63
63
```python
64
64
from flask import Flask
65
65
from flask_bootstrap import Bootstrap
@@ -90,7 +90,7 @@ Let us begin by creating a simple comment form. The information we want from a u
90
90
91
91
Let us now create the class that defines all the fields we want in our comments form.
92
92
93
-
`forms.py: Create a user comment form`
93
+
`forms.py`: Create a user comment form
94
94
```python
95
95
from flask_wtf import FlaskForm
96
96
from wtforms import StringField, SubmitField, TextAreaField
@@ -140,7 +140,7 @@ I have used Bootstrap to quicky display my comment form, though you can manually
140
140
141
141
With the form ready to be displayed, we will now update our `index()` view function to render it.
142
142
143
-
`routes.py: Render the comments form`
143
+
`routes.py`: Render the comments form
144
144
145
145
```python
146
146
from app import app
@@ -189,7 +189,7 @@ We will use `flask-migrate` to perform this migration. Install it in the virtual
189
189
190
190
SQLite, being the most convinient choice in developing small applications, expects certain configurations from `Flask-SQLAlchemy`. We first provide the location of the database in the application through `SQLALCHEMY_DATABASE_URI` configuration variable. This variable will source its value from the `DATABASE_URL` environment variable.
@@ -211,7 +211,7 @@ If `DATABASE_URL` does not exist, then I have provided a fallback value where I
211
211
212
212
The database will be referenced through a database instance. We will create a `db` variable that will be used to access the database.
213
213
214
-
`__init__.py: Database Instance`
214
+
`__init__.py`: Database Instance
215
215
```python
216
216
from flask import Flask
217
217
from flask_bootstrap import Bootstrap
@@ -242,7 +242,7 @@ Let is create a new module called `models.py` that will contain our database mod
242
242
243
243
The translation of our database into code will look like this:
244
244
245
-
`models.py: Comment database Schema`
245
+
`models.py`: Comment database Schema
246
246
```python
247
247
from app import db
248
248
from datetime import datetime
@@ -325,7 +325,7 @@ Since all user information is now stored in our `User` database which is linked
325
325
326
326
The first step is to update our database every time new data comes through the Comments Form.
327
327
328
-
`routes.py: Update the database`
328
+
`routes.py`: Update the database
329
329
```python
330
330
from flask.helpers import url_for
331
331
from werkzeug.utils import redirect
@@ -355,7 +355,7 @@ def index():
355
355
356
356
`form.validate_on_submit()` is used to validate the form. If the form is valid, the `user` object is created and added to the database. Otherwise, the index page will be displayed. I have added a flash message to notify the user that their comment has been posted. To see the message, we need to update our `base.html` template.
357
357
358
-
`base.html: Show flash message`
358
+
`base.html`: Show flash message
359
359
```html
360
360
<!-- Contents of all our pages will go here -->
361
361
{% block content %}
@@ -384,6 +384,7 @@ Try post a comment. If all goes well, then you should be able to see the flash m
384
384
385
385
We will display the comments in the index page. So, let us update our `index()` view function to display the comments.
386
386
387
+
`app/routes.py`: Display comments
387
388
```python
388
389
from flask.helpers import url_for
389
390
from werkzeug.utils import redirect
@@ -418,7 +419,7 @@ def index():
418
419
419
420
We query our `UserComment` database using the `UserComment.query.all()` function. This function returns a list of all the comments made by users in the database. We can then loop through the list and display the comments in the `index.html` page.
420
421
421
-
`index.html: Display comments`
422
+
`index.html`: Display comments
422
423
```html
423
424
{% extends 'base.html' %}
424
425
{% import 'bootstrap/wtf.html' as wtf %}
@@ -459,7 +460,7 @@ You should be able to see this:
459
460
460
461
So far so good. The last thing I would like to add to every user is an avatar. This avatar will be displayed in each user's comment. To add an avatar to each user, we will need to update our `UserComment` model.
461
462
462
-
`models.py: User Avatar`
463
+
`models.py`: User Avatar
463
464
```python
464
465
from hashlib import md5
465
466
@@ -500,7 +501,7 @@ Obviously, it is the admin of the website who will have the ability to delete co
500
501
501
502
We want to collect an admin's username, email address and the password to their accounts. Our model will define these columns and store the relevant data in the database.
502
503
503
-
`models.py: Admin model`
504
+
`models.py`: Admin model
504
505
505
506
```python
506
507
# ...
@@ -538,7 +539,7 @@ Create an admin migration script and apply these changes to our databae.
538
539
539
540
We can now update our `Admin` model by registering a new admin. We will begin by creating an admin registration form.
540
541
541
-
`forms.py: Admin Registration Form`
542
+
`forms.py`: Admin Registration Form
542
543
```python
543
544
from flask_wtf import FlaskForm
544
545
from wtforms import StringField, PasswordField, SubmitField
@@ -556,7 +557,7 @@ class AdminRegistrationForm(FlaskForm):
556
557
557
558
With the form created, we will now create a view function which will handle the registration of an admin user.
558
559
559
-
`routes.py: Admin Registration`
560
+
`routes.py`: Admin Registration
560
561
```python
561
562
# ...
562
563
@@ -582,7 +583,7 @@ Let us create the template that will be used to display the registration form. F
582
583
583
584
We will quickly display our form in the template with the help of flask-wtf.
584
585
585
-
`register.html: Admin Registration Form`
586
+
`register.html`: Admin Registration Form
586
587
```html
587
588
{% extends 'base.html' %}
588
589
{% import 'bootstrap/wtf.html' as wtf %}
@@ -617,7 +618,7 @@ Flask provides the `flask-login` package which we will use to help us manage our
617
618
618
619
Like other extensions, we will initialize it in the application instance.
619
620
620
-
`__init__.py: Initialize Flask-Login`
621
+
`__init__.py`: Initialize Flask-Login
621
622
```python
622
623
# ...
623
624
from flask_login import LoginManager
@@ -646,7 +647,7 @@ class Admin(UserMixin, db.Model):
646
647
647
648
Because `Flask-login` literally knows nothing about databases, it will need the application's help to load the admin. We will use a user loader function to load the admin by their ID.
648
649
649
-
`models.py: User Loader`
650
+
`models.py`: User Loader
650
651
```python
651
652
from app import login
652
653
@@ -656,7 +657,7 @@ def load_user(id):
656
657
```
657
658
With the Admin model fully prepared to handle user sessions, we will now create the login form.
658
659
659
-
`forms.py: Admin Login Form`
660
+
`forms.py`: Admin Login Form
660
661
```python
661
662
# ...
662
663
from wtforms import StringField, SubmitField, PasswordField, BooleanField
@@ -674,7 +675,7 @@ The template that will be used to display the login form will be `login.html`. L
@@ -701,7 +702,7 @@ The template that will be used to display the login form will be `login.html`. L
701
702
702
703
Finally, we will create the view function which will handle the login of an admin.
703
704
704
-
`routes.py: Admin Login`
705
+
`routes.py`: Admin Login
705
706
```python
706
707
from flask_login import login_user, current_user, logout_user
707
708
@@ -723,7 +724,7 @@ def login():
723
724
724
725
To make it easier for an admin to log in to their account, we will display a link in the navigation bar. If you noticed, the login page also contains a link to the registration page. So, there is no need to add a registration link beyond that. I have left out the _forgot password_ link because it is beyond the scope of this tutorial. However, you can take it up as a challenge and learn how you can implement it in the application.
725
726
726
-
`base.html: Add a login link`
727
+
`base.html`: Add a login link
727
728
```html
728
729
{% block navbar %}
729
730
<navclass="navbar navbar-default">
@@ -755,7 +756,7 @@ Now, if you click on the Admin link in the navigation bar, you will be redirecte
755
756
756
757
As an admin, you would want to protect your account by ensuring you log out once you are done moderating user comments. The `logout_user()` method from `flask_login` handles this.
757
758
758
-
`routes.py: Admin Logout`
759
+
`routes.py`: Admin Logout
759
760
```python
760
761
# ...
761
762
@@ -767,7 +768,7 @@ def logout():
767
768
768
769
We will create a condition in our base template to display the logout link only if the user is logged in.
769
770
770
-
`base.html: Display logout link`
771
+
`base.html`: Display logout link
771
772
```html
772
773
{% block navbar %}
773
774
<navclass="navbar navbar-default">
@@ -811,7 +812,7 @@ For now, we will display all the user comments just as they can be seen in the i
811
812
```
812
813
813
814
814
-
`admin_dashboard.html: Display Admin Dashboard`
815
+
`admin_dashboard.html`: Display Admin Dashboard
815
816
```html
816
817
{% extends 'base.html' %}
817
818
@@ -842,7 +843,7 @@ For now, we will display all the user comments just as they can be seen in the i
842
843
843
844
The view function to render the admin dashboard will be `admin_dashboard()`.
844
845
845
-
`routes.py: Admin Dashboard`
846
+
`routes.py`: Admin Dashboard
846
847
```python
847
848
# ...
848
849
from flask_login import login_required
@@ -863,7 +864,7 @@ I have added the `login_required` decorator to protect this page from unauthoriz
863
864
864
865
We are now ready to implement comment moderation. At the end of this section, our application will only show comments that the admin has approved. To begin, I will add a new field in the `UserComment` model to store the moderation status of a comment.
865
866
866
-
`models.py: Add comment moderation status`
867
+
`models.py`: Add comment moderation status
867
868
```python
868
869
# ...
869
870
@@ -882,7 +883,7 @@ I have set the default value of the `allowed_comment` field to `False`. This wil
882
883
883
884
The next step is to add two view functions to _allow_ and _delete_ each comment.
884
885
885
-
`routes.py: Allow and Delete Comment`
886
+
`routes.py`: Allow and Delete Comment
886
887
```python
887
888
@app.route('/admin/delete/<int:id>')
888
889
defadmin_delete(id):
@@ -907,7 +908,7 @@ I am identifying each comment by its ID. First, I query the database for first i
907
908
908
909
To make it work, let us update the admin's dashboard links to include the links to the `admin_delete()` and `admin_allow()` view functions.
909
910
910
-
`dashboard.html: Add links to admin_delete() and admin_allow()`
911
+
`dashboard.html`: Add links to update and delete comments
911
912
```html
912
913
{% extends 'base.html' %}
913
914
@@ -942,7 +943,7 @@ To make it work, let us update the admin's dashboard links to include the links
942
943
943
944
Let us update our `index()` view function to display only approved comments.
944
945
945
-
`routes.py: Display Approved Comments`
946
+
`routes.py`: Display Approved Comments
946
947
```python
947
948
# ...
948
949
@@ -978,7 +979,7 @@ Notice how only one comment appears in the index page whereas the admin dashboar
978
979
979
980
To ensure that we do not approve a comment twice, I will display an empty link reading _allowed_.
0 commit comments