不拘小节的小蝌蚪 · 现场演出深圳音乐厅官方网站· 1 月前 · |
寂寞的茶叶 · 关于公交都市创建情况的报告_ ...· 3 月前 · |
酷酷的柑橘 · 错峰出游!三代“童”游叹别墅!石梅湾艾美度假 ...· 3 月前 · |
酷酷的茶叶 · 导师个人信息 - 电子科大研招网· 1 年前 · |
快乐的马克杯 · 进群分享 不分秒t - OSCHINA - ...· 1 年前 · |
In this four-part tutorial series, you’re building a social network with Django that you can showcase in your portfolio. This project is strengthening and demonstrating your understanding of relationships between Django models and showing you how to use forms so that users can interact with your app and with each other. You’re also making your site look good by using the CSS framework Bulma.
In the previous part of this tutorial series, you built templates and views for displaying a list of all profiles, as well as individual profile pages. You also learned how to apply style rules defined by the CSS framework Bulma to make your pages look good.
In the third part of this tutorial series, you’ll learn how to:
At the end of this part, your social network will have all the pages you’d expect, and you’ll be able to create dweets on the back end and display them on the front end. Your users will be able to discover and follow other users and read the contents of the profiles that they follow. They’ll also be able to click a button that sends an HTTP POST request handled by Django to unfollow a profile if they want to stop reading a certain user’s content.
You can download the code that you’ll need to start the third part of this project by clicking the link below and going to the
source_code_start/
folder:
Get Source Code: Click here to get the source code you’ll use to build and handle POST requests with Django.
In this four-part tutorial series, you’re building a small social network that allows users to post short text-based messages. The users of your app can also follow other user profiles to see the posts of those users or unfollow them to stop seeing their text-based posts:
You’re also learning how to use the CSS framework Bulma to give your app a user-friendly appearance and make it a portfolio project you can be proud to show off!
In the third part of this tutorial series, you’ll continue working with Bulma-styled templates, and you’ll create the model for your text-based message content. You’ll also set up and handle HTTP POST request submissions on your Django app’s front end, which will allow users to follow or unfollow each other by clicking a button:
At the end of this tutorial, each user will be able to go to a new dashboard page to access a personal feed of dweets that’s based on which profiles they follow. They’ll also be able to follow and unfollow other users. That’s a giant leap ahead for your Django social network!
In this section, you’ll get an overview of what topics you’ll cover in this third part of the tutorial series. You’ll also get a chance to revisit the full project implementation steps, in case you need to skip back to a previous step from earlier in the series or if you want to see what’s still up ahead.
At this point, you should have finished working through parts one and two of this tutorial series. If you did, then you’re now ready to continue with the next steps of this tutorial series. These steps focus on the code logic for following and unfollowing profiles, as well as how to set up dweets:
After completing all the steps in the third part of the tutorial series, you can continue with part four .
To get a high-level idea of how you’re working through all four parts of this tutorial series on building your Django social network, you can expand the collapsible section below:
You’re implementing the project in a number of steps spread out over multiple separate tutorials in this series. There’s a lot to cover, and you’re going into detail along the way:
✅ Part 1: Models and Relationships
✅ Part 2: Templates and Front-End Styling
⏭ Part 4: Forms and Submissions
Each of these steps will provide links to any necessary resources. By approaching the steps one at a time, you’ll have the opportunity to pause and come back at a later point in case you want to take a break.
With the high-level structure of this tutorial series in mind, you’ve got a good idea of where you’re at and which implementation steps you’ll handle in the last part.
Before getting started with the next step, take a quick look at the prerequisites to skim any links to other resources that might be helpful along the way.
To successfully work through this part of your project, you need to have completed the first part on models and relationships and the second part on templates and styling , and you should confirm that your project is working as described there. It would be best if you’re also comfortable with the following concepts:
Remember to make sure that you’ve completed the first two parts of this tutorial series. This third part will pick up right where you left off at the end of the second part.
Note: You won’t be able to follow this part of the tutorial series if you don’t have the working project from the previous parts ready to go.
You can also download the code that you’ll need for starting the third part of this project by clicking the link below and going to the
source_code_start/
folder:
Get Source Code: Click here to get the source code you’ll use to build and handle POST requests with Django.
For additional requirements and further links, check out the prerequisites mentioned in the first part of this tutorial series on building a basic social network in Django.
At this point, you can access all profiles on the profile list page, and you can also visit users’ profile pages. Additionally, you can navigate between these views on the front end using dynamic links. At the end of this step, you’ll be able to follow and unfollow profiles through buttons on the profile pages.
Once you’ve added the possibility to follow and unfollow a profile, you’ll have recreated the back-end functionality that your Django admin interface provided for you out of the box when you set it up in the first part of this tutorial series.
Add HTML code with Bulma button styling to create two buttons for interacting with profiles:
<div class="buttons has-addons">
<button class="button is-success">Follow</button>
<button class="button is-danger">Unfollow</button>
</div>
A good spot for the buttons for following and unfollowing a user could be right below their profile name. Get your bearings on where that is in your own template code, then add the HTML shown above.
If you’re using the HTML from the profile.html
template, then you can add it as shown in the collapsible section below:
<div class="block">
<h1 class="title is-1">
{{profile.user.username|upper}}'s Dweets
</div>
<div class="buttons has-addons">
<button class="button is-success">Follow</button>
<button class="button is-danger">Unfollow</button>
</div>
</div>
<div class="column is-one-third">
<div class="block">
<a href="{% url 'dwitter:profile_list' %}">
<button class="button is-dark is-outlined is-fullwidth">
All Profiles
</button>
</div>
<div class="block">
<h3 class="title is-4">
{{profile.user.username}} follows:
<div class="content">
{% for following in profile.follows.all %}
<a href="{% url 'dwitter:profile' following.id %}">
{{ following }}
{% endfor %}
</div>
</div>
<div class="block">
<h3 class="title is-4">
{{profile.user.username}} is followed by:
<div class="content">
{% for follower in profile.followed_by.all %}
<a href="{% url 'dwitter:profile' follower.id %}">
{{ follower }}
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
After adding this HTML code snippet to profile.html
, you’ll see two buttons rendered under a user’s profile name.
If you go to http://127.0.0.1:8000/profile/1
, for example, you can ensure that Django’s development server is running and that you can access a profile page on your localhost. This URL shows you the profile page of the user profile with the ID 1
and includes the new buttons:
The buttons look good! However, it seems that you could click to follow a profile even if you’re already following it.
To create some distinction there, you could gray out the irrelevant button so that the relevant action will be more apparent for your users. Bulma should render your buttons grayed-out if you add an HTML class called is-static
. You can apply this class depending on whether or not the logged-in user is already following the profile that they’re viewing:
1<div class="buttons has-addons">
2 {% if profile in user.profile.follows.all %}
3 <button class="button is-success is-static">Follow</button>
4 <button class="button is-danger">Unfollow</button>
5 {% else %}
6 <button class="button is-success">Follow</button>
7 <button class="button is-danger is-static">Unfollow</button>
8 {% endif %}
9</div>
You’ve been working with the user
variable that Django sends with every GET and POST request. Note that you don’t even need to explicitly pass this variable to your context dictionary in views.py
. The user
variable holds information about the currently logged-in user:
Line 2: In this conditional statement, you’re checking whether the profile that you’re currently viewing is in the query set of all profiles that the logged-in user follows.
Lines 3 to 4: If the user already follows the profile that they’re looking at, then the Follow button will be grayed out by adding the is-static
class. The Unfollow button will be colored and appear clickable.
Lines 6 to 7: If the user doesn’t follow the profile that they’re looking at, then the Follow button will appear clickable, and the Unfollow button will be grayed out.
Line 8: In this line, you’re closing the conditional statement.
By adding a bit of code logic through Django’s template tags and styling, you’ve made it clearer to users that they can only follow profiles that they’re not currently following and that they can only unfollow those profiles that they’re following already.
Navigate to a profile page URL such as http://127.0.0.1:8000/profile/1
or, if you’re still there, then just reload the page to see the changes:
However, even though the information is now displayed in a more user-friendly way, clicking the clickable button doesn’t actually do anything. For this, you’ll need to create an HTML form and handle the form submission in your code logic.
Handle POST Requests in Django Code Logic
Your next step is to implement the logic of what should happen when someone clicks one of these buttons. For this, you’ll need an HTML form so that you can submit the data and handle it in your view:
2
{%
csrf_token
%}
3
<
div
class
=
"buttons has-addons"
>
4
{%
if
profile
in
user.profile.follows.all
%}
5
<
button
class
=
"button is-success is-static"
>
Follow
</
button
>
6
<
button
class
=
"button is-danger"
name
=
"follow"
value
=
"unfollow"
>
7
Unfollow
8
</
button
>
9
{%
else
%}
10
<
button
class
=
"button is-success"
name
=
"follow"
value
=
"follow"
>
11
Follow
12
</
button
>
13
<
button
class
=
"button is-danger is-static"
>
Unfollow
</
button
>
14
{%
endif
%}
15
</
div
>
16
</
form
>
Lines 1 and 16:
You wrapped your two buttons in an HTML
<form>
element and added the HTML attribute
method
with the value
"post"
to clarify that you’ll send data with this form.
Line 2:
You added a
CSRF token
through a convenient template tag that Django provides. You need to add this for security reasons if you want to allow your users to submit forms in your Django app.
Lines 6 and 10:
You added two HTML attributes to both
<button>
elements:
name
defines what key you’ll use to access the value in your view function. You set this key to
"follow"
for both buttons.
value
defines what value the form will send to your view function under the key name defined in
name
when you press one of the buttons. You set the value of the
Follow
button to
"follow"
and the value of the
Unfollow
button to
"unfollow"
.
You won’t see any change on the front end of your web app after adding this code, but the changes are necessary so that Django can forward the user-submitted data to your view logic. You also need the attribute values defined in lines 6 and 10 to distinguish which button the user pressed on the back end.
With all the front-end logic set up in
profile.html
, you can switch to
views.py
, where you can pick up the user-submitted data and handle it:
Python
5
def
profile
(
request
,
pk
):
6
profile
=
Profile
.
objects
.
get
(
pk
=
pk
)
7
if
request
.
method
==
"POST"
:
8
current_user_profile
=
request
.
user
.
profile
9
data
=
request
.
POST
10
action
=
data
.
get
(
"follow"
)
11
if
action
==
"follow"
:
12
current_user_profile
.
follows
.
add
(
profile
)
13
elif
action
==
"unfollow"
:
14
current_user_profile
.
follows
.
remove
(
profile
)
15
current_user_profile
.
save
()
16
return
render
(
request
,
"dwitter/profile.html"
,
{
"profile"
:
profile
})
Because of how you set up the form in
profile.html
, the form will redirect back to the same page, which means that Django will pick up the request with
profile()
. It works this way because of how you set up your URL configuration. This time, however, Django sends an HTTP POST request that holds the user-submitted data, and you can address this in your code update:
Line 7:
You introduce a conditional check to see whether the incoming request to your Django view function is an HTTP POST request. This will only be the case if someone submitted the form on
profile.html
by clicking either the
Follow
or
Unfollow
button.
Line 8:
You use the
user
attribute from Django’s
request
object, which refers to the currently logged-in user, to access that user’s
.profile
object and assign it to
current_user_profile
. You’ll need access to this user’s profile later on to change whom they’re following.
Line 9:
You get the user-submitted data from the
request.POST
dictionary and store it in
data
. Django puts data in
request.POST
when a user submits a form with the attribute
method="post"
.
Line 10:
You retrieve the submitted value by accessing the data at the key
"follow"
, which you defined in your template with the
name
HTML attribute on your
<button>
elements.
Lines 11 to 14:
You set up a conditional statement that either adds or removes the user profile from the currently logged-in user’s
.follows
, depending on which button they pressed. The two buttons submit different values for the
"follow"
data key, which you use to distinguish between the two buttons.
Line 15:
You use
.save()
on
current_user_profile
to propagate the changes to
.follows
back to the database.
Finally, after all this conditional action—which Django only executes when the page is called with a POST request from a form submission—you render the same template again.
render()
will reload the page and correctly display the changed follower list after a button click.
Note:
In case you haven’t created profiles for you and your existing users you may run into an
RelatedObjectDoesNotExist
error when performing the POST request. To prevent this error you can verify that your user has a profile in your
profile
view:
Python
def
profile
(
request
,
pk
):
if
not
hasattr
(
request
.
user
,
'profile'
):
missing_profile
=
Profile
(
user
=
request
.
user
)
missing_profile
.
save
()
profile
=
Profile
.
objects
.
get
(
pk
=
pk
)
if
request
.
method
==
"POST"
:
current_user_profile
=
request
.
user
.
profile
data
=
request
.
POST
action
=
data
.
get
(
"follow"
)
if
action
==
"follow"
:
current_user_profile
.
follows
.
add
(
profile
)
elif
action
==
"unfollow"
:
current_user_profile
.
follows
.
remove
(
profile
)
current_user_profile
.
save
()
return
render
(
request
,
"dwitter/profile.html"
,
{
"profile"
:
profile
})
When you call the
profile
view, you first check whether
request.user
contains
profile
with
hasattr()
. If the profile is missing, then you create a profile for your user before proceeding.
You can now follow and unfollow the profiles of other users on your social network. Confirm that this works as expected by exploring the profiles in your profile list and selectively following and unfollowing them. You should see the list in your sidebar update accordingly.
With this, you’ve fully connected the follow and unfollow back-end logic with the front end. You added an HTML
<form>
element and two buttons in
profile.html
. You also implemented the code logic in
profile()
that translates the button presses into changes that affect your database.
Step 8: Create the Back-End Logic for Dweets
At this point, you can choose to follow and unfollow user profiles through the front end of your app. However, even if you
do
follow another profile, there’s nothing there to see! At this point, users of your social network can’t create any content. Changing this will be your next challenge.
At the end of this step, you’ll have created the back end for the content of your social network—short text-based messages called
dweets
—that users can post to your app. You’ll also be able to create dweets for users through the Django admin.
Just as you brainstormed in the
project overview in part one
, your social network will focus on short-form text-based messages. In memory of old-school Twitter, you’ll set the character limit to 140 characters.
Note:
Up to now, the type of content that users post could have been anything. Your focus was only on the connections between users of your app.
Now you’re getting specific. If you wanted to allow a different form of content in your social network, you’d need to branch off in another direction at this point.
You planned to create a model that focuses on the fundamentals of what content your users will share on your social network. You also decided that you’ll tie the dweets to a user account and that, apart from the text body, the only thing the dweeets need to record is the time of submission:
The
entity-relationship (ER) diagram
shows that your
Dweet
model will have a foreign key relationship to Django’s built-in
User
model. Each user of your social network will be able to create many dweets associated with their account.
Make the Model
You need a way to store the user-created text-based messages in your database. For that, you’ll need to create a new model in
dwitter/models.py
:
Python
class
Dweet
(
models
.
Model
):
user
=
models
.
ForeignKey
(
User
,
related_name
=
"dweets"
,
on_delete
=
models
.
DO_NOTHING
body
=
models
.
CharField
(
max_length
=
140
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
user
:
This field establishes the model relationship to Django’s built-in
User
model. You define that it’ll be a foreign key relationship, which means that each dweet will be associated with a user. You also pass
"dweets"
to
related_name
, which allows you to access the dweet objects from the user side of the relationship through
.dweets
. Finally, you specify that orphaned dweets should stick around by setting
on_delete
to
models.DO_NOTHING
.
body
:
This field defines your content type. You set it as a character field with a maximum length of 140 characters.
created_at
:
The final field of your new model records the date and time when the text-based message is submitted. Setting
auto_now_add
to
True
on a
DateTimeField
object ensures that this value gets automatically added when a user submits a dweet.
And with these three fields set, you’re finished creating your
Dweet
model! Next, you need to apply the changes to your database by running the
makemigrations
and
migrate
management commands:
Shell
After running both of these commands, your changes in
models.py
have been applied to your database. Your back end is all set to record dweets, but so far, you don’t have a way of submitting them through your web app.
Add Dweets Through the Admin Interface
Eventually, you want your social network users to submit dweets through the front end of your web app. First, however, you’ll make sure that everything you’ve built so far works as expected. You’ll start by adding the functionality to create dweets through your admin interface.
To get access to your new
Dweet
model in your admin interface, you need to register it:
Python
from
django.contrib
import
admin
from
django.contrib.auth.models
import
Group
,
User
from
.models
import
Dweet
,
Profile
# ...
admin
.
site
.
register
(
Dweet
)
If you head over to your admin interface after doing this, you’ll see that the
Dwitter → Dweets
option now shows up. Click on the
+ Add
button next to it and create a new dweet:
Note that you need to assign an existing user object to the dweet that you want to create. You can select one from the dropdown. You also need to add text for the body of the dweet. You
don’t
need to add the date when you’re creating it because Django will handle that automatically after you click on
Save
.
By providing the user and the text body, you’re able to create a new dweet through your admin interface:
However,
Dweet object (1)
isn’t an exceedingly descriptive name for the submitted dweet. It’d be more user-friendly if you could see who wrote it, when they wrote it, and at least the beginning of the text. You can change how Django displays a
Dweet
object by overriding
.__str__()
in the class definition of
Dweet
:
Python
class
Dweet
(
models
.
Model
):
user
=
models
.
ForeignKey
(
User
,
related_name
=
"dweets"
,
on_delete
=
models
.
DO_NOTHING
)
body
=
models
.
CharField
(
max_length
=
140
)
created_at
=
models
.
DateTimeField
(
auto_now_add
=
True
)
def
__str__
(
self
):
return
(
f
"
{
self
.
user
}
"
f
"(
{
self
.
created_at
:
%Y-%m-%d %H:%M
}
): "
f
"
{
self
.
body
[:
30
]
}
..."
By adding a custom
.__str__()
method that returns a
Python f-string
consisting of the username, the created date, and the first thirty characters of the message body, you’ve improved how Django renders dweets on the admin interface:
With this change applied, the dweet overview page in the Django admin interface will remain helpful and readable even once your users have added many additional dweets.
Note:
In preparation for the following steps, you should create a couple of dweets and assign them to different users of your app. Make sure that you have at least three users and that they all have a few example dweets so that you can see which dweets show up when you follow or unfollow profiles.
In this step, you created a new model for the text content of your Django social network, registered it in your admin interface, and improved how Django displays the objects. In the next section, you’ll add the code to tell Django to show these dweets on the front end of your web app.
Step 9: Display Dweets on the Front End
At this point, you have the profiles set up, and you can create dweets through your Django admin interface. At the end of this step, you’ll be able to view dweets through the front end, and you’ll be able to display the dweets of profiles you follow on a dashboard page.
If you haven’t created any dweets through the admin interface yet, then head back there, make a few dweets, and assign them to different users. Having some dweets to check on will be helpful once you’ve set up the dashboard page to display the dweets of the profiles you follow.
Display Personal Dweets on Each Profile Page
First, you’ll head back to
profile.html
, where you’ll add code to display all dweets of the user associated with this profile. Later, you’ll make another site that’ll show all the dweets of people you follow.
On the profile page, you have access to
profile
. How can you iterate over a user’s dweets in a similar way to how you did with the followers of a profile?
If you think back to writing
Dweet
, you might remember that you set
related_name
to
"dweets"
. The name you defined there gives you reverse access to the associated
Dweet
objects through the
User
model. Further, you can access a linked
User
instance through the
Profile
object that you’re passing in the context dictionary:
Python
Nice! With this code, you’re taking a complete tour through all the model relationships that you’ve set up during this project. Go ahead and use it in
profile.html
so that you can see each user’s dweets on their profile page:
{{
dweet.body
}}
<
span
class
=
"is-small has-text-grey-light"
>
(
{{
dweet.created_at
}}
)
</
span
>
</
div
>
{%
endfor
%}
</
div
>
<
div
class
=
"block"
>
<
h1
class
=
"title is-1"
>
{{
profile.user.username
|
upper
}}
's Dweets
<
form
method
=
"post"
>
{%
csrf_token
%}
<
div
class
=
"buttons has-addons"
>
{%
if
profile
in
user.profile.follows.all
%}
<
button
class
=
"button is-success is-static"
>
Follow
</
button
>
<
button
class
=
"button is-danger"
name
=
"follow"
value
=
"unfollow"
>
Unfollow
</
button
>
{%
else
%}
<
button
class
=
"button is-success"
name
=
"follow"
value
=
"follow"
>
Follow
</
button
>
<
button
class
=
"button is-danger is-static"
>
Unfollow
</
button
>
{%
endif
%}
</
div
>
</
form
>
</
div
>
<
div
class
=
"content"
>
{%
for
dweet
in
profile.user.dweets.all
%}
<
div
class
=
"box"
>
{{
dweet.body
}}
<
span
class
=
"is-small has-text-grey-light"
>
(
{{
dweet.created_at
}}
)
</
span
>
</
div
>
{%
endfor
%}
</
div
>
</
div
>
<
div
class
=
"column is-one-third"
>
<
div
class
=
"block"
>
<
a
href
=
"
{%
url
'dwitter:profile_list'
%}
"
>
<
button
class
=
"button is-dark is-outlined is-fullwidth"
>
All Profiles
</
button
>
</
div
>
<
div
class
=
"block"
>
<
h3
class
=
"title is-4"
>
{{
profile.user.username
}}
follows:
<
div
class
=
"content"
>
{%
for
following
in
profile.follows.all
%}
<
a
href
=
"
{%
url
'dwitter:profile'
following.id
%}
"
>
{{
following
}}
{%
endfor
%}
</
div
>
</
div
>
<
div
class
=
"block"
>
<
h3
class
=
"title is-4"
>
{{
profile.user.username
}}
is followed by:
<
div
class
=
"content"
>
{%
for
follower
in
profile.followed_by.all
%}
<
a
href
=
"
{%
url
'dwitter:profile'
follower.id
%}
"
>
{{
follower
}}
{%
endfor
%}
</
div
>
</
div
>
</
div
>
{%
endblock
content
%}
This does the trick! The iteration works after stepping through your model relationships, and you can view the dweets of the current user in a pleasant way thanks to Bulma’s stylesheet:
Check out another user profile by clicking on one of the links that you set up earlier. All your profile pages are working as expected, and they look lovely! You can now explore everyone’s followers, whom they’re following, and their dweets. You can also follow or unfollow each profile with the click of a button. That’s exactly what most users would expect to see on their profile page.
You’re still missing a way to display a feed of all the dweets of all the profiles you follow. You’ll implement this functionality by updating your dashboard view.
Create a Dashboard View
You already set up a placeholder dashboard view early on
in part two of this series
, which means that the appropriate routing is already defined, and Django will call
dashboard()
when you navigate to the base URL. So far, there’s not much to see, as it only renders your base template. Now you’ll update this endpoint to make it more useful and display your dashboard page. On your dashboard, you want to be able to do two things:
-
Read all dweets from the profiles you follow
-
Submit a dweet
You’ll tackle the second task in the next part of this series. For now, you’ll focus on displaying the dweets of all the profiles you follow. Update
dashboard()
in
views.py
to point it to a different template:
Python
Of course, that template doesn’t exist yet. To keep Django from complaining, you head over to
dwitter/templates/dwitter/
and create a new template called
dashboard.html
and add some draft code logic to confirm that it works as expected:
1<!-- dwitter/templates/dwitter/dashboard.html -->
3{% for followed in user.profile.follows.all %}
4 {% for dweet in followed.user.dweets.all %}
5 <li>{{dweet.user.username}} ({{ dweet.created_at }}): {{ dweet.body }}</li>
6 {% endfor %}
7{% endfor %}
After adding this code snippet to dashboard.html
and navigating to the base URL at localhost:8000/
, you should see an unformatted list containing all the dweets of all the profiles you follow mixed together.
Note: If nothing new comes up, make sure that your admin user follows itself and at least two other profiles. You can also check that these users have some existing dweets in your database.
Before you make this list look better with Bulma’s styling, it’s worth it to first revisit the model relationships that you’re chaining together in your Django template:
Line 3: You dive into the user
object that Django sends with every POST or GET request. It refers to the logged-in user, currently your admin user. With .profile
, you access the profile of your admin user, which you set up when you extended the Django User
model. The profile has an attribute called .follows
that holds a collection of all the user profiles that this profile follows. Finally, with .all
, you access an iterable of that collection.
Line 4: You nest another for
loop into the previous one. Here, you access followed
to get at each user profile that the currently logged-in user follows. Then you step through the .user
object and its related_name
, .dweets
, to access all the dweets that this user has written. With .all
, you again access an iterable of that collection.
Line 5: You now have access to each dweet in dweet
. You use that to pick out the information you want from each text-based message and assemble this information in a single HTML list item.
It’s pretty powerful how you can use Django’s model relationships to find precisely the information that you’re looking for, even if it requires you to drill through a succession of different steps! Keep in mind that it works this way because of how you set up your models in earlier steps:
You can take a pencil and fetch the database draft that you created in part one. Try to think about how your models are connected, and make sure that you understand how and why you can access the dweets in the way you did above before moving on.
Now you can buff up dashboard.html
so that it fits with the design of the rest of your social network:
<div class="column">
{% for followed in user.profile.follows.all %}
{% for dweet in followed.user.dweets.all %}
<div class="box">
{{ dweet.body }}
<span class="is-small has-text-grey-light">
({{ dweet.created_at }} by {{ dweet.user.username }}
</span>
</div>
{% endfor %}
{% endfor %}
</div>
{% endblock content %}
By extending your base template and adding some styling through Bulma’s CSS classes, you’ve created an attractive dashboard page that shows your feed displaying all the dweets of all the profiles you follow:
Each user will see their own personal feed of dweets, based on which profiles they follow. That’s a giant leap ahead for your Django social network!
In this step, you added a new dashboard template that displays a personal feed of dweets, and you also added code to profile.html
that shows each user’s dweets on their profile page. In the next step, you’ll add a Django form that allows users to submit dweets from their dashboard page.
Conclusion
In this part of the tutorial series, you continued to build the front end and the back end of your small social network using Django. Your app users can now follow and unfollow other user profiles and view the text-based messages of profiles that they follow.
In the process of building this project, you’ve learned how to:
-
Create the
front-end interface
to
follow and unfollow
profiles
-
Submit and handle a
POST request
in Django using
buttons
-
Set up the
model
for your text-based content
-
Build
styled templates
to display content on the front end
-
Use intricate
model relationships
in template code
In the next and final part of this tutorial series, you’ll create a Django form that allows your users to submit new dweets through the front end. You’ll also make sure that the content submissions are valid. Finally, you’ll improve the user experience by adding navigation and sorting the dweets to display the newest messages first.
You can download the code that you should have by the end of this part of your project by clicking the link below and going to the
source_code_final/
folder:
Get Source Code:
Click here to get the source code you’ll use
to build and handle POST requests with Django.
Next Steps for Your Basic Social Network With Django
Now that you’ve completed the third part of this tutorial series, you can continue to the final part, where you’ll
build and submit HTML forms with Django
.
In the upcoming part of this tutorial series, you’ll add the code logic that will allow your users to create content on your web app by using a form. You’ll make a
Django form
in
forms.py
, connect it to code logic in
views.py
, and render it in a template so that your users can submit dweets from the front end.
You’ll build out the
dashboard page
as the main page of your social network. Users can then submit their content so that it’ll show up on the platform together with the dweets of the profiles that they follow.
Keep in mind that you can keep referring back to earlier steps while working on this project. For example, it might be helpful to consult the plan that you drafted in the
project overview
of the first part of the tutorial series and update your plan as you make your way through the rest of the steps.
Martin likes automation, goofy jokes, and snakes, all of which fit into the Python community. He enjoys learning and exploring and is up for talking about it, too. He writes and records content for Real Python and CodingNomads.
» More about Martin
Master
Real-World Python Skills
With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:
Master
Real-World Python Skills
With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:
What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.
Commenting Tips:
The most useful comments are those written with the goal of learning from or helping out other students.
Get tips for asking good questions
and
get answers to common questions in our support portal
.
Looking for a real-time conversation? Visit the
Real Python Community Chat
or join the next
“Office Hours” Live Q&A Session
. Happy Pythoning!