![]() |
|
[Tut] How I Designed a Personal Portfolio Website with Django (Part 2) - Printable Version +- Sick Gaming (https://sickgaming.net) +-- Forum: Programming (https://sickgaming.net/forum-76.html) +--- Forum: Python (https://sickgaming.net/forum-83.html) +--- Thread: [Tut] How I Designed a Personal Portfolio Website with Django (Part 2) (/thread-101087.html) |
[Tut] How I Designed a Personal Portfolio Website with Django (Part 2) - xSicKxBot - 05-03-2023 How I Designed a Personal Portfolio Website with Django (Part 2) 5/5 – (1 vote) We are designing a personal portfolio website using the Django web framework. In the first part of this series, we learned how to create Django models for our database. We created an admin panel, and added ourselves as a superuser. I expect that by now you have used the admin panel to add your sample projects. You are required to go through the first part of this series for you to follow along with us if you haven’t already done so. In this series, we will create a view function using the sample projects. By the end of this series, we will have created a fully functioning personal portfolio website. The View Function ![]() We can choose to use class-based views or function-based views, or both to create our portfolio website. If you use class-based views, you must subclass it with Django’s Code: ListViewCode: DetailViewFor our portfolio website, we will use function-based views so that you can learn how to query our database. Open the Code: views.pyCode: from django.shortcuts import render
from .models import Project # Create your views here. def project_list(request): projects = Project.objects.all() context = { 'projects': projects } return render(request, 'index.html', context)We import the Code: ProjectsThe Code: contextCode: render()Code: index.htmlCode: contextThis Code: viewCode: def full_view(request, pk): project = Project.objects.get(pk=pk) context = { 'project': project } return render(request, 'full_view.html', context)This Code: viewCode: pkTemplate Files ![]() We have to create two template files for our view functions. Then, a Code: base.htmlCode: base.htmlCode: base.htmlCode: <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <div class="container"> <a class="navbar-brand" href="{% url 'index' %}">Personal Portfolio</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="{% url 'index' %}">Home</a> </li> </ul> </div> </div> </nav> <div class="container"> {% block content %}{% endblock %}
</div> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>The Code: aCode: {% ... %}Code: index.htmlCode: block contentCode: endblockCode: divCode: base.htmlAs we will see, any template file inheriting from the Code: base.htmlThe Bootstrap files are beyond the scope of this article. Check the documentation to learn more. Create the Code: index.htmlCode: {% extends "base.html" %}
{% load static %}
{% block content %}
<h1>Projects Completed</h1>
<div class="row">
{% for project in projects %} <div class="col-md-4"> <div class="card mb-2"> <img class="card-img-top" src="{{ project.image.url }}"> <div class="card-body"> <h5 class="card-title">{{ project.title }}</h5> <p class="card-text">{{ project.description }}</p> <a href="{% url 'full_view' project.pk %}" class="btn btn-primary"> Read More </a> </div> </div> </div> {% endfor %}
</div>
{% endblock %}The Code: index.htmlCode: base.html![]() Using the Code: forCode: imgNotice that the Code: aCode: project.pkAgain, notice the Code: block contentCode: endblockCode: index.htmlCode: base.htmlCode: block contentCode: endblockFinally, the Code: full_view.htmlCode: {% extends "base.html" %}
{% load static %}
{% block content %}
<h1>{{ project.title }}</h1>
<div class="row"> <div class="col-md-8"> <img src="{% project.image.url %}" alt="" width="100%"> </div> <div class="col-md-4"> <h5>About the project:</h5> <p>{{ project.description }}</p> <br> <h5>Technology used:</h5> <p>{{ project.technology }}</p> </div>
</div>
{% endblock %}That’s all about our template files. Notice how everything is linked to our database model as we learned in the first part of this series. We retrieve data from the database, pass them to the view function, and render them in the template files. ![]() We haven’t let Django know of an existing templates folder. Go to the Code: settings.pyCode: TEMPLATESCode: templatesCode: TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], #add these 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, },
]![]() We need to hook up our view functions to URLs. First is the project-level URL. Open the Code: urls.pyCode: from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), path('', include('portfolio.urls')),
] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)We register the file using the Code: include()Code: http://127.0.0.1:8000Code: index.htmlCode: ifNext are the app-level URLs. Create a Code: urls.pyCode: portfolioCode: from django.urls import path
from .views import project_list, full_view urlpatterns = [ path('', project_list, name='index'), path('<int:pk>/', full_view, name='full_view'),
]The Code: full_viewCode: http://127.0.0.1:8000/1Hoping that everything is set, start the local server, and you will see everything displayed. Conclusion We have successfully come to the end of the second series of this project. The first series is here: First Part: How I Designed a Personal Portfolio Website with DjangoIf you encounter errors, be sure to check the full code on my GitHub page. Our app is now running in the local server. In the final series of this project, we will see how we can deploy this to a production server. |