Django is a popular web development framework that uses Python.
We just published a course on the freeCodeCamp.org YouTube channel that will help you improve your Django skills by teaching you how to create a digital résumé using Python and Django.
Bobby Stearman developed this course. Bobby has created many popular courses on his own YouTube channel.
For this course, Bobby collaborated with a designer to provide viewers with a free digital résumé template. You will learn how to customize the template and use Django to create a dynamic backend.
A great résumé page can help you get jobs. And using Django for the backend will allow you to add content to the page without updating the HTML.
The course is broken up into four main sections:
- Selecting and downloading a template
- Starting a Django Project
- Modifying the Frontend
- Creating the Backend
Watch the full course below or on the freeCodeCamp.org YouTube channel (1.5 hour watch).
Improve your Django skills by building a digital resume website.
Bobby Stearman teaches this course he provides a free resume website template, and will teach you how to program the backend using Django.
Hey, everyone is probably format dead code in here.
And I've put this course together today, because if you're anything like me, you've applied for numerous developer roles over the years.
And you've been successful some of the time, but you've missed out on most.
Now this is because there are so many talented developers out there.
So you must stand out in a crowd, it's absolutely paramount that you do.
So I'll show you today how to digitize your resume using Django.
Now, the reason we're using Django is twofold.
Firstly, with Django, you have a built in admin page, which allows you to create read, update, delete objects.
So this will avoid the need to update the source code in your project.
So we can add objects in the admin page, and it gets rendered straight into the HTML, which is fantastic.
And secondly, it gives us a chance to polish up on our Django skills.
So we will be firstly binding a template, we've got a template that you can download for free, we'll be then creating the Django project, we'll be building out the back end the front end, and then we'll be stringing it all together.
So this will take just over an hour.
So that's jump straight into it.
This is the template that we're going to be using.
So this has been designed by James Granger design, a colleague of mine, it's fantastic.
He's put this together, we're not charging anybody, you can access this template in our GitHub repository, which.
so decoding resume template like i say completely free all you need to do is clone a repository and you will have access to it i will show you today how to then string that template in to a django project.
Okay this is what the template looks like at the very top.
hereyou have an avatar you have a bioor that will be abio we then got a link to download a resume so we need a pdf version of your resume and, we'll attach that to a user profile.
We have key skills coding skills with a slide bar, we have some certificates that we can scroll through, we have portfolio section, we have a testimonial section.
And we also have recent posts.
That's the index page, we have a portfolio list view.
Okay, we have a blog ListView, which is almost the same and a contact page.
The portfolio and blog pages will also have detail pages as well.
And they will be rendered to the front end with a rich text editor, which we will also add to Django admin.
So what we add in a rich text editor will be rendered directly as it's seen in admin to the front end, which are fantastic.
Like I say, we will be creating objects in Django admin without the need to change the source code for the project.
Okay, and this Contact Us form allows potential employers to contact you add the name, email, and a message and submit.
So that is the template.
That is what we will be building today in Django.
So first thing that we need to do is use a text editor.
I'll be using visual code studio today.
And this is opened up in development.
So the first thing I've got a terminal open here as well.
First thing that we need to do is create a virtual environment.
Now I'm using a virtual environment wrapper.
So I can just use the command make virtual env V and we will call this resume demo.
Okay, and that will go ahead and it'll create a virtual environment on my machine and it will fire it up.
The reason I know it's fired up is because we've got this in brackets here.
So resume demo.
So now that's there.
We now we need to we now have access to pip.
So we can pip install Django.
We will also pip install pillow.
And we'll also pip install Django ck, editor.
Okay, they're the three that we will need straight off the bat.
Okay, once that's finished installing all of that, we will then start a Django project.
And we will call it again same as the virtual environment.
We'll call this resume demo.
Don't worry if you have this come up.
It's just telling you that you need to update PIP just simply paste that in there.
Bob's your uncle that's installed the latest version of PIP.
So we're all good to go.
Right? So now we need to see D.
No, we don't, we need to start a project.
So because we've installed Django, we can now access Django admin.
And we say start project.
And we'll call this resume.
Okay, that was start project, we can now see D into resume demo.
There we have it.
And let's open that up in my browser here.
There we have it, it's that you know what, let's open up a new open a folder.
To filament, we just open it up here.
So we haven't got all of the other stuff.
Let's open up terminal.
And we will go work on.
Again, that's another command from virtually every rapper.
So we've got these pop ups.
So we'll call we'll run, resume demo, I've got the virtualenv up and running again.
And this is the project directory.
So when you start any projects, you get the manage.py file.
And then you'll also have the resume, resume demo directory with the Dunder init, file, your ASCII settings, URLs and whiskey.
Okay, so what we'll do now we can access the Manage dot p y, what we can do, we can Python, manage dot p y was Stein app.
And we'll McCool this made.
And now we will go about so what I'm, what I'm going to do is I'm going to be referencing my other screen, because I've built this project in a previous stage to make sure that all works.
And it speeds things up rather than having to watch me do typos and and have to debug all of my code.
So I'm going to move this through from a from another screen copy and pasting it across that is nice and smooth, and we aren't going to be too clunky.
So the first thing we're going to do is we're going to open up settings dot p y.
Okay, and this is what it looks like when you first install the Django project.
So right at the top here, import OS.
So that allows us to access the operating system, this project will require the use of static files.
So the reason we have O S is because we'll be using that in a second to join the base directory to the new static file directories.
We have this at the base dir which be referencing that's the secret key.
Now in a production environment, you would secure that maybe in an EMV of some sort, but we won't In this tutorial, debug is true allowed hosts are good.
What we need to do is we need to add main into our installed apps, we also need to add CK editor there we go.
That will allow us to use a rich text editor in the admin page middleware.
We don't need any middleware that I know of just double check.
No, we don't, but we will be adding a contact processor.
So the context processor will go in here.
Processes dot p y, the contact process P y will be looking like this.
So we'll be importing the user model here as the built in user model.
And we'll be just adding a keyword argument called meat to the context process.
And that'll all come in, you'll understand what's happening soon enough.
We're going to set in stop p y, we can now add that context processor to the context processor here.
So we'll have read resume demo is contact processes dot project context.
We don't need that last one there.
Okay, so now this context here so this keyword mi will be accessible in the templates that we're building out later on in this demo.
So whiskey application, we don't need to do anything there.
We're just going to use the built in SQL lite three database, you could upgrade that to PostgreSQL or Myos.
QL but we weren't in this.
So when we make the migrations, there'll be a DB SQ lite file that appears, but don't worry too much about that.
We'll change the N to GB.
And what will then do is we will add the static files does and the static route and media route and what have you.
Okay, so I won't go through what we're trying to do here.
So they sit in a static directory, we will be accessing them things like logos, things like Cascading Style Sheets.
So the settings here allow us to or it tells the system where those directories are going to be and how they're going to be managed.
So that is it.
We don't need to do anything else to settings.
But we do need another fine file in here called URLs dot p y.
I was already unnecessary.
Yeah, we don't need that.
So I'm getting carried away.
So any URLs, p, p y file, I will then copy all of this across.
So we need to add include path, we need to bring in settings from django.com.
And we need static from Comp dot URLs dot static.
And we will be adding the path means that URL, so we haven't even created that far yet.
But we'll do that in a second.
But we're adding this to the URL pattern.
So all of the URLs in the main dot URLs file that we'll create in a second, will then become part of our URL patterns.
Okay, we could call it main namespace equals main.
So that is what we'll call it in the app in a few seconds.
And then we've got this here.
So if settings dot debug, we then add the static URL, and a static route to the URL patterns.
And we also do the same for media URL and media route.
So in development environment, we will simply have a static directory in here.
And we'll have a media will be called media file.
So as we save an avatar or an image, it will add a directory and I'll add the image or the file to the directory within Media Files directory.
Okay, so that is the URLs there.
Main, what we need to do is straight away we need URLs dot p y, right? So we will have that file.
And we will create that will be referencing views that we haven't created yet, but we'll add it in there anyway.
Okay, the reason we're doing that is because trying to do this in in a good order.
Normally, you would add this after you create views, and you won't create the views until you added the models, but we're referencing this file in this urls.py file.
So we're bringing in path of views, okay, which we haven't created yet.
The app name is main.
In fact, what we could do, because we might need to make some migrations, before we do this, so I will comment those out.
Okay, so because we haven't produced we haven't created those yet.
So we will start in order.
So what you start with, you start with models, okay.
So models, models are translate to database tables, okay.
So we will create a model, the name becomes the table name, and fields become the rows, sorry, the columns, and then for each object that we save becomes each row in that table.
So that's basically what a Django model represents copy.
And we'll paste, okay.
So, bringing in models, and we're bringing in a built in user model that is in contract or models, we need that because we're going to extend that for the user profile.
Okay, we'll be extending it using something called signals.
But we'll go through that in a second.
We then bring in a slugger five because we need a slug for our blog, and our portfolio will then bring in CKEditor.
So this is a Django CK editor is a rich text field.
So this, we can add this rich text field to the blog and portfolio.
So there's create a skill model.
We have a meta class, and I always add these not necessarily needed by default, it will, it will Pluraleyes the name by add it in there anyway.
It's not the end of the world.
Okay, so name equals this is a char field.
So these will be the skills so we go back in here.
These will be these skills here.
Okay, this is what we're trying to replicate.
So we want coding skills and we want key skills.
So we've got the name of the of the skill, the score.
So if this was a key skill, or sorry, a coding skill, we'd want to score it because we want the sliding bars on here to represent 95 or 80% of the skill or the knowledge or your expertise in a certain skill, we then have an image the reason we've got an image or firefield, because this is an SVG.
So these images here SPGs.
So for each key skill, we want an image, okay, so we'll do that.
And then his key skill, which is a Boolean, so it's true or false.
So if this is true, then this object would represent a key skill.
If it's false, it represent a coding skill.
So we then have a string function, and it just returns self dot name.
Okay, so that's our skill model, we then have a user profile.
So this is what extends the built in user model.
That's why we've got a one to one field here.
On delete cascade, we'll only be producing or creating one user profile.
So that will be us as a super user, we have an avatar, which has an image field, this is why we brought in pillow upload to and this will create a directory in media files called Avatar.
And when we save a file in there, that is where that avatar will go.
Got a title of bio.
So the idea of a bio is this bit here.
So that will, that'll appear there, when we add it to the templates.
We then have skills which has many too many.
Okay, so it'd be many to many of these skills here.
And then we have a CV, which is a file filled, this will be uploaded to a CV, CV directory.
So each time you update your CV on your paper copy, you'll update this, upload it to this field here, and it will save the new copy in the directory.
And then the string function or method here just returns first name and last name of the user model will then got a contact profile, which has a timestamp, which that gets added automatically.
Okay, so it's a date time field without a name, email message.
So if we look back on here, we're going to contact name, email message.
That's what we're trying to capture here.
Testimonial, we have a thumbnail, this is for the testimonial on home.
So what we're trying to do is just replicate all of these elements, right.
So this is we need a phone now we need a in here, we're going to have the name of the person who's actually given a testimonial and the role.
And then we have the quote itself.
So in here we've got name, role, quote, and is active, we're adding this is active Boolean field, all of these models are the testimonial with a portfolio in a blog, because although we want to add a testimonial, we want to be able to quickly switch it on and off.
So if it's inactive, we don't want it to be shown up on the website.
So that's why we've got an inactive field there.
So the reason we're doing this is because if we can add an image to a media model, that image gets saved into the media file, the media directory within the media files directory, and we then have access to that URL when we're creating the rich text editor image.
It'll All Make Sense a little bit later.
But that's just an easy way of accessing static files in a template.
When we're messing around in admin, which I'll show you what that means soon.
So his image the reason why this we're doing this is because you could technically add a URL here for a video.
And then if this was a false, it would be a video URL safe saving huge mp4 is in your database.
So if the URL is blank, then sorry, if sorry, self URL is not blank, then his image becomes false.
Okay, so programmatically adjust this image dependent on the URL field.
And then we've got a portfolio.
So a date.
So this is the date in which the job was done.
Name, Description body.
So this is important.
This is the rich text field.
This is what this is the rich text editor that we'll be updating in the admin page, what you see is what you get rendered in HTML or in the browser.
So that is really important that you have that there.
So Rich Text field there is being referenced right at the top of the page here.
So it's part of CKEditor dot fields.
Then got an image which be the thumbnail if you like, gets uploaded to portfolio.
But then got a slug, which is a slug field and is active.
See the slug field is populated here with the save method.
So if not self ID so basically if there's a new new object, we slug or phi, the self dot name, which what it does it all of the the characters become lowercase and all spaces are then underscored.
So it becomes a slug.
then got the get absolute URL here, so is portfolio slash slugs, self dot slug, we do exactly the same for blog.
Okay, so blog is basically same as portfolio.
Then lastly, because certificate, which is a date name type description is active, nothing fancy going on in in certificate there.
So that's models, what we'll then do, we will register all of those into our admin.
So we can access them, this is one of the most important parts of it, we want to be able to access all of those models in our admin page.
Okay, so what we're doing, we're importing all of them from models, all of the new models here.
And then we're using a decorator admin dot register, we're registering the user profile, but then we're adding a class under that called User Profile admin.
What this does, this will allow us to display.
This will allow us to display the fields that we want any admin page.
Okay, so let's display ID user, we've then got timestamp name, and then also on here, we've got read only fields.
So the slug we cannot change, we don't really want to be changing that because a slug could be used, you could send a blog link, you could have a backlink somewhere for a blog page, and you don't really want to be changing the slug because then that link becomes inactive.
So when the slug is produced, that remains the same no matter what.
So we have a read only field.
So that's what's going on in admin, we then want a way of creating the user profile using signals.
So we'll go main new file, signals dot p y.
And we will add this code to signals, what it's doing it's important post save the button, use a model, important receiver, which is a decorator.
And then we're bringing in the user profile, which we just created.
Now what this signal is, it's a receiver.
So when a object is created when a user object is created Pfizer's signal to this signals.
P y file, there's a receiver that picks up that signal.
And then this function is called by so as create profiles, we bring in as keywords, sorry, arguments, send an instance created, and then some keyword arguments.
So if created, so if the user object is created, then we want to create user profile.
And that will become user profile that objects create a new user, which is a one to one field, if you remember equals the instance.
That is what's going to be used to create the user profile.
So when we create a super user, in a few moments, that user will be created the signal before this will receive the signal, Bob's your uncle will have a user profile.
But we need to wire this signals.py file into the apps dot p y.
And how we do that is we overwrite the ready method we just haven't boy itself.
Brilliant, okay, and then we need to import main dot signals.
That's all we need to do.
So when this will fire up the app itself, the main app, and it will just say right when ready, then we need to bring in signals and only signals will all work.
So when the when the app is running signals is all working, okay? What we then need to do is create some model forms.
So a model form for our contact form forms dot P, why have I added the I have this fine.
And what we'll do and forms oh, let's delete, delete that.
I'm going to go in here.
And we want a new file, not a new directory.
So forms.py paste everything in.
Oh, so I do apologize, copy and paste important forms.
And we're also importing contact profile, which is the model that we made in the models dot p y file.
So this will be a model for Okay, so we'll be we don't actually need these, I never took these out when I was playing earlier.
Actually, it's worthwhile showing you.
So let's save that.
So this is a model form and this represents a form against the model that we just created a contact form.
So what you need to do is we need to create these variables one for each field that we want in the form itself.
So we've got name and then we want to this here is the representation of this is what will be rendered in the HTML on the front end, okay.
So forms that this is a character field max length equals 100.
So the reason that's 100 is because in the models file, or is it, let's go into Contacts.
There we go.
Name max length 100.
So that's why we're doing that.
We then have required Teresa, this is a field that is true.
So this will render an input element, and it will be required true.
Okay? Widget equals forms dot text input.
So this is a text.
So the input will be type equals text, then we have some attributes.
So we have a placeholder.
And in this case, it will be star which will be rendered in the actual input itself to be stopped for name, dot dot.
And then you can add class.
Now we don't actually need class, if you were to buy a template, the forms that you have in the template may have certain classes, this is where you would add those classes to make sure that the form that gets rendered on the front end is exactly the same as what is in your template.
Okay, so that's what we've got there.
We don't actually need them, because we're not using Form control in our templates, so I'll remove them.
So email, email field, max length is 254, which is completely standard for an email field.
And then we've got a placeholder button got a message.
Now this is slightly different.
It's not text input, it's a text area.
Now we want rows six.
Now, this all depends on your template.
In my template, we have six rows, okay, so that's why we've got row six.
But you might have 10, or whatever placeholder is message, then we have a class meta model, which this represents his contact profile in the fields, we want to render his name, email message, that is our forms.py file, then what we need to do is add our views.
So let me copy all of that.
I'll go in here in our views.py file, and I'll dump them all in there.
Okay, so right at the top here, have added import messages.
The reason we want to import messages is when a form when a form is valid.
And when a form is saved, we then want to render a message, so that the message pops up and says thank you very much for submitting the form or what have you.
So I'm bringing in messages to do that.
From dot models import, and then we want to import all of these different models.
From Django dot views, import generic, we're going to be using the generic views, template view, list view, form, view, so on and so forth.
These built in form views, they're all class based views.
But they're they're built specifically for tasks that happen regularly.
So for instance, a list view, you're rendering a list of objects, so it just does all the hard graft in the background.
So you've got, you can render, you can render a web page, they say, a form view, with only two or three lines of code, which is great.
You can also do function based views.
But I like to use these built in built in views.
So we've got index view, this will be our homepage.
Okay, so we're using generic template view.
So we need we in a template view, you need to add the template name.
So what name what template are we using to render this view, in this case is going to be main index.
So what we'll do is we need a directory in main, called templates.
within that directory, we need another one called main.
Okay, within there, that is where we will add our templates.
We'll do that shortly.
We don't need to do that just yet.
We then call the method get context data.
And we call a super call there and then context we can then add keywords to context here.
So testimonials, so we want testimonial certificates, blogs, and portfolio, these are objects.
So these are these will be added to context and we can reference them in templates so that we can actually render a list and do a for loop using template filters and things like that.
So we're calling testimonial objects and we're filtering everything where is active equals true, this is where that field in models comes in really handy.
So in testimonial, okay, is is active, defaults to true.
But if in admin we click it to be untrue or false, then it will not appear in the context because we're filtering out everything that's sorry, filtering out everything that's untrue.
So is active equals true.
So only true objects, live objects, active objects, with no certificate, same again, blog, same again portfolio, same again and then we're adding those keywords to context and then we return context.
So now in index we can reference testimonials, and that will be a list of objects.
We can render, contact view, this is a form view.
So you name the template, you name the Form class, and then a success URL.
This is where the user will be redirected when the form is valid.
So we then call the form valid method, pass through self and form.
So this is the form, which we're passing through, which is a contact form, form dot save.
So we save the form instance.
And then we send this message here, which is message dot success.
And a Texas Thank you, we will be in touch soon.
And that is what will be shown on the front end, we then have a portfolio view which has a list view, the model is portfolio, you do have to have a page named by.
So this will only show 10, or the first 10 objects.
And then the template name the query set.
What we're doing there is we're filtering the query set is active true.
Okay, so only true portfolios.
Same again, exact except for this will be the slug.
So we'll add this in the URL.
So it will show the detail.
So to show the object that has the slug in the URL itself, blog view, identical to the portfolio view and a blog detail view is identical to the portfolio detail view.
The only difference is we're looking at different HTML files, okay.
So they are the views, we will save that just looking at my what we have not done is we have not created a requirements file.
So we will go PIP freeze quirements dot txt.
And let's just create this.
So these are all the requirements for the project got Django, you can see Django CK editor, we've got pillow, because we're messing around with images.
And that's all the requirements happy days.
So what we now need to do is we need to make migrations.
So Python manage.py, make migrations, we then need to Python manage.py migrate.
And then we need to go Python manage.py.
Create super user that will then allow us to create, they'll move this up a little bit.
That will then allow us to create a super user see that will default to Bobby Bob, but they know anyway, Bobby at did coding.com password, it'll ask you twice, it won't look like you're typing, but it will pick up the keystrokes.
There you go.
So super user created successfully.
So what we'll do is we'll go Python, manage dot p y, run server.
Tell you what we haven't done we haven't uncommented out the URLs.
So we've we've wired in the views.
But we haven't uncommented these out.
So I'd do that quickly.
So back on the URLs here.
Remember, we wire this main app into our URL comp file.
So everything that appears here a URLs specific to main.
So path is blank, this will be our homepage.
So this will be your localhost port 8000.
This will be an index as view because we're using class based views, you must use this.as view, if it was a function based view, you wouldn't need that name is home.
So that's how we reference it in the template.
So it'd be main hope that's how we would reference it, I'll show you it when we work through that shortly.
Contact view same again, got portfolio view is portfolios, just pluralized then we've got this is important.
So this is the detail view.
So this is a portfolio slash slug.
Okay, so the URL will have the slug of that object in it.
And that's how we're capturing it in the detail view.
Same again for blog and blog slug.
Okay, so they are the URLs.
So if we now go back in our terminal, we've got that up, I should just be able to double click that.
There we have it.
That is not one seconds.
Just because I've got the server running on something else.
There we have it.
You just had a sneak peek.
So I had a server running on the previous project or the project that I'm copying from.
So what you saw there is what I'd built earlier.
Okay, so nothing's working because we haven't got a template there, right would expect that.
So if we go to admin, which is the built in admin page, and then sign in with the user credentials we've just added there we have it.
Okay, so we've got the authentication models, this is the one that we've just created.
So we'll give me a first name.
We could have done that in the terminal.
But there we go.
So now got an email, first name, last name, that signal should have produced a user profile, which has great.
So this is the user profile now.
Okay, so that's choose avatar.
So what we'll do is this go into desktop development, I'll go into, this is the one I was playing with earlier.
Media files, Avatar, let's use that title is back end.
Developer bio, this is just a demo bio.
And what will then do is we will add a skill.
So this can be Django.
And I'll put that why not let's go 100% is not a key skill, this is my coding skills.
Safe, we'll have peace, HTML, will have this as 95.
Save will have CSS will have this as 90.
And then what we'll do, we'll add another one, which will be Java scripts.
Let's just change things up.
But 75 say let's have a key skill this time.
So we have people person we'll have it doesn't really matter on a number their key skill.
But what we'll do, we will add media files skills.
Open save, team, player, I mean, you can put whatever you want in yours.
This is just me building it out is a key skill save.
And we'll have.
So starter will have that as key skill icon.
These all come in their template, by the way, all of these images, and CV.
So if I go into that, these were ones that I've added earlier.
So there we go.
So what I'm doing is I'm building out the the admin page.
So this is the benefit of using Jango.
Right, so this built in admin page allows us to create so at any point, we could change the avatar, at any point, we can change the bio, so I adding to the bio.
Yeah, so if you save it, that will then become the new bio.
So you don't have to when you get this in a production environment, you don't have to go into source code, we need to do change the back end, that's the benefit of doing this.
Okay, so we've added let's add a testimonial.
So choose the thumbnail MIDI files use that one name, Bobby, Role Manager.
This is a test quote.
Now do save and add another word you know what we'll just quickly flash through this name Bobby to manager to quote too and I won't do this all of them because it'll be a waste of your time.
Bobby three, manager three and quote three there now the three objects.
So what we can do, we can make the inactive that won't appear you see is active.
Okay, so that won't, won't be rendered on the front end.
But those keep that in there.
See the benefit there.
So I've done user profile testimonial skills, they're all in there.
That was when we were adding them here.
We had to do click Add and it adds it to that skill because it's a many to many field.
Again, you can change these at any point, change that to, you know, or not in a key.
Change CSS to 292.
For instance, save that becomes 92 Okay, media files, let's add one of these images.
What I thought that's just the thumbnail from another video that I've produced.
random image Save conduct profiles, we don't need that certificates, we'll just add one certificate shall we? So now now name would be let's go advanced Django, course Free Code Camp description, this is a test this retune.
That will do, we won't add three certificates, you'll get the gist.
And then what we need to do is add a blog profile.
So this is where the rich text editor comes into it.
So author, we can have Bobby stemmen name, we can have this as test blog and have description, test this group Gen.
And then what you can do is you can have you can just have a two, this is a header, and whatever we put in here is what will be rendered, what you see is what you get, right.
So this is a random scription.
And then this is what I wanted to show you the the media file.
So this guy open up another browser, okay, go back in the media files, this here gives us access to this URL, okay to get that, that is the URL of the image we just saved into our database, sorry, into our static files.
Okay, if we go into blog, now add an image to hear just toy around with this, it sometimes won't render right on the front end.
But if you toy around with a rich text editor, you can get it to work.
So if we add an image URL, just paste the URL that we just added in there, all text test image.
Up in main media, I'll move it on there.
That's not right.
I want that.
Let's copy that there we go.
Right width, we'll have these, these are links.
So if you just put 800 you can stick a border on there, if you want.
We'll align it left.
There's a whole bunch of other bits you can do on their link advanced, so click OK.
Okay, and then we'll choose an image this will be the thumbnail for the image.
So you can you can pick the same one if you'd like is active, safe.
For girls, we'll add a portfolio as well.
We'll do exactly the same again.
So now now name is the best description test description.
And then we'll have header to header.
This is a this option is the end.
And in between that we will add an image.
Same again, don't need to get too fancy with with the put 100 I think stick a board on there.
We'll put four on this time and left.
Okay, choose a fun now.
Okay, I think we've now got all the bits and pieces.
So that took a little bit of jiggery pokery to get that all up and running in the backend.
But also, we now need to do see a really I could could now duplicate these blog, the blog, so we've got blog to blog, three, whatever, but it's no biggie, you can do that in your own time.
I've just constructed the backend in a way that I know this is gonna work.
And just if you're following along, get this done, get three blogs get three portfolios, and it will look fantastic on the front end.
So that is the backend basically done what we now need to do is wire in the front end.
So we have got the templates here.
The directory for the resume is here.
So what we need to do is we need our static files.
So we will take these will copy them and we'll dump them into this is our this is the project by the way.
So new folder, we'll call this static and we will paste them simply paste them in there.
So they are all of a static files that we need.
Go back into the resume and we then want all of these so keep your finger on control.
Just select all of them.
You don't need to license the readme, copy them.
I want to add them to Main templates main will paste.
Okay, though all of the templates, we now need to wire them in.
Okay? If I just open one of these now it's gonna look terrible, right? Okay, because it just doesn't know what a static files are just doesn't know what's going on.
Okay, because they're now in a Django project.
If I open up them in the original, it will work, because that's just the way it's wired up.
So we don't need that.
Let's close that.
Let's close that.
There's close that.
Let's go back into Visual Studio.
So these are now the templates that were put together.
We'll bring our term we don't need to see the term, you know what? I'll close it down for now.
We don't need that.
So this is the index file.
So it's a standard HTML file.
Okay, you've got head, you've got body.
And within that body then got a navigation.
So we've we've tried to be as detailed as we can, or helpful as we can on the documentation of these HTML files.
So this is the navigation bar.
This is the content for this particular page.
There's loads of sections a bit further down, actually, it's just hide them, it'd be a lot easier, a bit further down, we've then got the footer.
And then we got the scripts, these are the body these are the scripts here.
Okay, nothing's going to work because it's referencing files that Django just doesn't know where to find them.
So if I was to render this, this index page, so in fact, this, go ahead and do it.
So new terminal, work on resume demo, Python manage.py, run server.
And all of the links are all squished.
So we need to load static files.
And we need to wire all of this in.
So that's what we're going to go and do.
And the way you do this is we need a base html.
So we will save index as base dot HTML.
And what we then need to do is create a another directory in Maine.
We'll call this partials.
And within here, we will need a new file called messages dot HTML.
We need another one in here called nav dot HTML.
That'll be the navigation element.
File, and we'll call this butter HTML.
So what we need to do is you need to dissect up this HTML, so that we can then use template tags.
So Django has a range of template tags that allow you to easily include other parts of HTML, which you need to do is just reference the path.
So we'll go ahead and do that.
So right at the top of the page, open up my other projects that go my base html, what you need to do, and you need to listen, most of them actually is load static.
We then go down, we go down all the way from the top here.
So we've got author, which had decoding and James Granger design, we then got canonical, which we need to add the context processor, if you remember in settings dot P, why is it so we added the contact processor here, but if you see here, all you always have access to request.
So that's what we need to get hold off here.
So it's request dot path.
Okay, so that is what you add in canonical.
In fact, I'm just gonna copy this across to save me messing about.
We then have a link which is home.
And then what we'll what we're using here is a temporary technical URL.
So relationship home, this is main.
So this is the app main, and it's called home, which is our index page.
We then in description when these SEO tags really, in the head of the HTML file, this is how I always managed them.
I add a block, template tag and I call it description.
And this allows me to have a description of a HTML page in the actual.
I'll show you what I mean in a second.
And then I have another one for keywords.
We've got the icon, this little icon appears at the top of the web browser.
And this is trying to find images.
But it can't find images because images, where is what is the path that we need to reference the static file.
So what we'll do, we'll link that we have it so we're using the static template tag, we're loading static at the top here.
And then we're referencing the static here.
So now we're looking in a static directory, in a directory called images.
And we're looking for icon dot jpg.
Now, in static, we don't we have images, okay, so we're looking for icon, which is icon.
Okay, so we're looking for that.
That's what we're looking for.
Happy Days, and we've got static.
So static, again, we're looking for CSS, we haven't got the path.
So we need to reference static, again, with style css.
So what we'll do is we will add all of these, okay.
And I always have a block template tag here.
And I always call it extend header.
This allows us to use CSS specific to a certain page within that template, rather than having it loaded on every page.
It's very, very handy doing that.
Okay, we've then got the body.
Okay, so what we're going to do here is, I'm going to copy that.
And I'm going to remove the header element.
And so obviously, this one gonna do, well, okay, so this is the header, the header remains the same on all of these pages.
It's not like we have a, if a page is active, then it is highlighted.
We don't do that in this template.
So you don't need to worry.
So all of this here can be cut, and can be done dumped into nav dot HTML.
So first off, we'll have load static.
And then we'll dump all of that navigation in here.
And then in the base html, what we need to do is, include it, so use another HTML tag, those include, so we're now including main.
So that's the main app, partial.
So the main directory, partials nav dot HTML.
So we don't need all that HTML there CS repeating ourselves, we also need to add some code, which isn't in the template, and I believe one second.
Now is here, right? Okay.
So there's an IF template tag like an ad in here.
So this is just some code that I use occasionally.
So if messages are rendered to the HTML document, so for messaging messages, so if this is a messages, dictionary or list, so for each message, it will render a script.
So this will pop up with a little alert at the top of the screen with the actual message.
In that case, it will be thank you for contacting us, we'll get back to you soon.
So that is our messages, HTML for going back in a base, we can then import or include messages into the body, so it always appears in the HTML, then we need to do the same for all of the content and all of the footer.
So we go back to the footer state for sorry, the footer element, we'll cut that we'll dump that in footer.
Again, load static, don't forget to do this.
Because you will run into an error.
And we'll just tidy up a little bit, bring it all back.
Oh, there we go.
And the base, we will then include that copy that's the footer.
And then with the content we're going to do is we're going to have a block.
So we'll have block content.
And then we'll have and block.
Okay, so this is important, right that little block there is what we're going to be using when we render the index html.
So in the index html, it will contain all of this HTML the content essentially, and we will use a different template tag in index to extend base so index will then be a combination of this HTML and the base html.
Okay, so we will cut that we're going to index would highlight.
So we're going to index we'll highlight everything and we'll paste it.
And we will bring that back to tidy it up a little bit.
There we have it.
Okay, so now at the top of this page, we will need a whole bunch of stuff, which I'll show you what we're going to do here, copy.
And we'll paste that in.
And I'll walk you through on doing section.
One I want at the bottom at just closing off the block.
And block, save, and I'll just go from the top right.
Okay, so we're extending main base, okay, so when we render the homepage is looking for index html.
And it's slotting in all of the information in this HTML in the blocks that we're stating.
So everything that's in a block content will be interjected, we injected into this block.
That's how it works.
Okay, so we'll save that.
So this one becomes static J, s, static J.
S, and then we add a footer hit.
Okay, all in all template should I say? So this block content is what will be rendered into this block? Okay.
This block title is what will be rendered into? Where is it? Can't see wood for the trees? How did I even add that in there? One second.
I might not have done.
I did, I just didn't copy it across.
I do apologize.
So title will be blocked title.
So the title here, anything we put here, which we could put did coding dash home, that will be rendered into that block there, okay, description that will be rendered into that block, and so on and so forth.
CSS, if we had a special CSS file that we want it on this particular page would add it here.
Content would have it here.
All we got to start contents don't want that.
Now, the last thing we need to do is we need to change all of the images that this is referencing, okay, so this is all looking for images here.
So what we'll do, we'll Ctrl H.
And what we need to do is static images slash what that will do that will replace all of everywhere it finds speech marks, images, forward slash it will replace with this code here, which is what we want is nine occurrences.
And then with a jpg dot jpg part of it, we will just go dot jpg.
We do that.
So where we just we just want to replace it all.
Save, and I think we've also got an SVG.
Yeah, there we go.
SVG s as well.
Dot SVG and play.
So now if we save that, I think that's it, I think.
So we need to do for this index page.
Now, we won't go through every page well.
So what we're doing for indices exactly what we need to do for every single page.
So contact, for instance, and I'll show you what I mean on contact, and I won't do all of the others, because you can do that yourself.
I'll just copy those code across from my other screen.
But I'll show you what to do with contact in a second.
But if I now that it looks like it's still the server is still up and running.
So we're now update this.
There we go.
is looking for logo, it can't find that because we haven't changed or we haven't updated the images in enough.
And it's probably the same at the bottom here.
We haven't done it in the footer either.
But everything else we're rendering, okay, okay.
He said there's not links to the back end yet, which would do that in a second.
So footer, I won't surround with the footer.
I'll literally just go a copy.
Okay, so what I've done, this is now the footer.
So I've changed all of the links to static and see that static images.
Then at the bottom here, rather than saying 2001 I've used another template tag called net So that will always have the most recent year.
So if when when we hit the first of January 2022, it will just show 2022 rather than 21.
Okay, save that nav will do exactly the same, I will a copy.
Again, you will have access to this project from GitHub, so don't worry too much, you'll have access to all of this code.
Or one, I haven't changed that this index dot HTML needs to actually change to URL main home, otherwise, that link won't work.
But it's looking for logo, which is in the static directory.
And it's adding a URL link to all of this.
So the home link at the top of the page, and I'll be main home portfolio will be portfolios, blogs, and contact.
So all of those links will now work.
Go back into the browser update, this now works, if you click it, it will take you back home.
If you click contact, it'll take us to the contact page, which looks beautiful.
So let's fix that quickly.
Well as the homepage is working, but we're doing exactly the same as what we just did on on the index page.
Okay, so all of this is exactly the same, we don't need the No Contact page, right? It's the CSS can't find it, we need to change all of that.
But save me doing all of that, again, all I really need is the context section, right? Content section.
I don't need any of the any of the footer or anything like that, all I need is the content.
And if I go index, and if I just copy everything from here, up, go into contact and dump it here.
That should I don't need that.
That can all go back a little bit on like to be nice and tidy.
Again, exactly the same as index, we're extending the base html, we're loading static, and then we can change all of this.
But again, this is why I like block, block, template tags.
So we can add whatever we want in here.
And that will be the new title for this particular page.
Okay, CSS scripts.
And this section here, right, so let's focus on this a little bit, because it's quite important.
So contact us below.
This is the form that we've currently got.
Okay, but we need to make this a Jango format.
So what we need to do is add a method equals, this is a post.
And the action is the URL that we want to be referencing.
So this is contact.
So the reason we're putting that is because in our URLs, this is a URL, so it's contact, okay, then we need to use because this is a post, not a get request or anything like that we need in here CSRF token that will add a hidden element with a CSRF token, which will then work, then, instead of these inputs, what we need is just copy across base just form and then reference the name.
So if I take those, if I dump those in here.
Okay, so rather than being inputs, we're now rendering the form.
Now the form is contact form.
That's what we produced in there in this forms dot P, why am I bringing in the Name field, the email field, the message field, we need to change that to message.
Sorry, that's an error on my part.
That is it.
So we need to do, but we need to close off the block, which don't forget to do that because there will be an error.
That is the contact form done.
Don't need to do that.
All we need to do just double check that.
There we have it.
Okay, so technically, now, if I was to put Bobby stemmen Bobby at the coding.com.
Message, this is a test message.
Now click Submit, hopefully.
We'll be in touch soon.
If we go into the database, go into contact profiles.
There we have it.
Okay, that's very, very useful.
That just means that you and this is another reason why we're using Django, any employer, anyone who wants to contact you using your contact form, you have a record of the timestamp and who it was, what the message was in the database.
So let's go back into our projects.
We've done index with OnContact.
Now that's focus on Let's go on to portfolio.
Same again, don't need any of this gunk above content.
In fact, all we need is all of this copy portfolio, paste that in there, we'll close the block off at the bottom of the page.
And we will once we find the bottom of the content scripts thing is that there, no, that's the footer, don't refer to that.
And block, save.
Okay, so we now just bring that back a little bit.
And that doesn't really matter.
That's all good.
The only thing is, we've got some images use here.
But I'm not going to change all of those.
That's not that's not a problem.
And we're not wiring this into the backend just yet.
So I'm just making the templates like they are.
So that's what you would do to each of them.
But don't get too carried away, because you need to add some Django template tags, like for loops so that we can actually render real information.
So we'll do that.
But I'm not going to do the detail for that one and the blogs or do that right at the end, I'll just copy and paste and walk you through it.
But let's focus on the index page.
So at the minute, we have got this here.
So we've changed this image.
So yeah, he's shown a picture of me.
But that's because that image is in the static files, what we need to do is we want to reference the avatar that we've saved against the user profile.
And how you do that is you don't need to reference static, now, you just need to use me, which is in the context.
Context processor, says me, okay.
But as the user profiles, so we now saw the user model.
So we now go user profile, dot avatar, which is the field, and then you want the URL of that, save.
If we now go back into the homepage, here, go home, that will still show just now what it's doing, we go inspect, is now picking up media avatar.
So this is the actual image that we saved against the profile rather than the file is in a static file, which is exactly what we want.
So I can now change this in the user profile to another image.
Let's choose a file.
And you know what, I'll just stick that in there.
And save file go back in here.
There we go.
It's not ideal, but it gives you an idea what we're doing here.
So choose file, go back in here going to Avatar, chase that and save again, Bob's your uncle, there you go.
So what we then need to do, we need to wire up all of this, all of this, the CSV file here.
And that's what we'll do now.
Okay, so hi, I'm, you can go me, dots.
First name, because this is the user profile.
And then you can use a filter called title.
Now, if I put Bobby all lowercase in the back end in the database, that would render a capital letter followed by all lowercase a, what this be, I think this is title.
Me dots, user profile, dot title, I think I won't go through all of these B's because you'll get the gist of it.
So this will be mi dot user profile dot bio.
So if we now go back in here, and click Update, they have it.
So Hi, I'm Bobby a back end developer.
This is just a demo bio, go back in the database, go back in the bio, dot dot, dot, dot, dot dot dot noticably.
Geek plus enter, or save.
There we go.
That's how that works is really, really handy.
So if we then go into the button, so download, so what we need here, we want to link to the CSV file, which is linked to our user profile.
So this will be me dot user profile.cv dot URL.
Nat should now because it got a download attribute, if I click that, it will then download my CSV.
CV sorry, you open it and that's the CV that I've got on that profile.
Okay, which is really handy.
Contact that's currently saying contact HTML we want that as a See, I hope you understand What I'm doing here, I'm just going through, and I'm adding Django template tags to allow us to programmatically change this and render information from a database, which is really good.
So that's contact.
Now that link, I'm saving it as I go, that link will now take us to the contact page.
Okay, and then what we'll do, we'll quickly do this, and then I'll copy everything across on my other screen, because it will take too long.
So we'll go into Yeah, we do this one.
In fact, I'll copy it, you know what I'm going to copy it across and walk you through what I've done.
So far, I take everything from my index.
Now I go into here, go everything from there.
So all of that work I just done, I'm just going to copy and paste over anyway, because it's already done on the other screen.
Okay, so you know what? Let me go back quickly.
Before I do that, because I want to show you what we're actually replacing.
So in this section, there's going to this section certificates, right.
So this is a slider.
So this is a slider outer.
So that's what we're looking at.
We've then got the Swiper slide.
Okay, so these are the elements.
So that's one certificate, that's to an s3, okay? Well, I don't want those three.
I want the ones that are in the database, okay, so I don't want them to at all, but I want this, but rather than showing what is going here, I want it to render what's in the database.
So to do that, we would use a for loop or see in said, Tiff IR cuts there we go to tiff cuts.
And then we want to if if c.is active then render this If not, don't render anything, right.
So we'll then close off the F and F and M close off the four and four, okay, so this is now a for loop, right? But what is rendering is loaded, obligate.
So what we've won is there's no link for the certificates, but you'd put you could if that was a blog, you'd put the URL template tag.
So we wants this to be C dots just check the field.
Certificates I think are the bomb here certificate so this could be title that'd be title.
This would be C dot date dot date see dot? What is this going to be? I needed to name title okay see, this is title that will be in this case for my example would be Free Code Camp.
And then you have this would be description.
C dot description.
So now rather than rendering gobbly gook is rendering actually something from the backend certificates.
The reason I'm accessing that is because it's in the context.
I added it in the context in views Okay, so if you go here, that's what I'm accessing.
So it's all active certificates.
Go back in index and save that my hoping I haven't bagged anything up.
So that's now showing one okay, because we've only got one in the database.
But if I go to certificates and click inactive save that will won't render anything.
So can you see what I'm trying to do here? That's nice that so every refresh done, okay, so I'm not going to go through and do everything else because you can see what we're trying to achieve you need to add for loops and if template tags to render the right information against this template, okay, so we'll go about and I will add this content here.
Paste save And then render it out.
And blog got to end blocks don't want to end blocks, save, go back.
I've got to block content as well.
Okay, that's that's always fun.
Sorry, I'm racing through.
I'm trying to There we go.
Let's delete that one save that should now work.
There we go.
So this is now all rendered from the back end.
So we're going to save certificate if we're going to skills, find our change HTML to 98.
Save that, update 98%.
And these leads will change as well.
So if I change that to 50%, you'll probably see what I mean, actually.
So I go 50.
There we go.
Team players, self starter is looking at different images, certificates.
We've got one in database featured work, I've got one testimonials, or put three in there, if you remember.
But if we was to make one inactive, for instance, save that.
There we go.
We've only got to enter.
Okay, test blog.
And if you were to click View All what it will then do, it will then take you to the blog page, but we haven't done that yet.
Okay, so I will quickly add all of these blog details.
So copy for Ghana blog details.
So what we're doing here, blog dt, actually, and we'll do a blog.
Copy, and we're going to blog, just a normal blog list page.
Save, if we go and render this now it should look good.
There we go.
Okay, so there's rendering my one blog that I've got.
So this is a list view, if I added another blog, it would appear there looks really, really good.
So if I click on this, it'll open up the blog details view.
Okay, and well, okay, that doesn't that didn't render too well.
So this when I say you need to mess around with the CKEditor, because it does some reason it renders some of the information incorrectly.
But that's fine.
You know, this is just playing playing with the information there.
So we're going to blogs, blog profile.
Why there is I just I wonder what that looks like that might help.
This is the end right, you can see what I've done.
Now I've just added some bits, it's because the image is probably too small for the for the actual screen.
If I was to make it a bit bigger.
Let's go back in there, make this image properties, change that to what 1000 So have a look.
There we go starting to do something different now.
Okay, so go play around with it, what you see is what you get with a rich text editor, but it just allows you to design a different blog.
So all of your blogs don't need to look the same.
But you can use the same template, which is great and really good benefit of using Django here.
So if I now open this, all we've done is in the blog detail page.
We have got Yeti object dot name, author.
So this has always been pulled through from the backend.
But this is what's important.
Okay, so the object of body if I was to remove safe, all it renders is raw HTML.
So this is the HTML that the rich text editor is creating.
But because we're using the safe template filter, it actually renders the HTML into something tangible that we can actually see and is rendered well on the front end.
So if I change that now back to safe save there we go.
And I'll quickly just for giggles I will change the details page copy this one, where is it? There we go.
Save portfolio, copy and portfolio safe so if I now go into here and go into Portfolio there we go and click on portfolio data.
Remember this is good again.
It's because the image that we've got in here portfolio let's change this image properties.
So let's put that as 1000.
And now probably work now.
There we go.
Again, our Tinker again.
But then look if we were to mark this as the active in your portfolio, it won't work.
Okay? To be honest, that might still work.
You could also put in the view that if that if the queer, so if the object is marked as inactive, then you can do a render redirect, so you can redirect back to the portfolio's list.
So it will never show a URL, but I haven't done that in this instance.
So that is it.
That is the template done.
So we have now got a digitized resume.
That is entirely.
That is entirely made in Django.
And we can change every single key element of this resume without having to change any of the core any of the code in the background.
So that's brilliant.
That is more or less the end of this.
I will just recap, right? So what have we done? We've just digitized a resume, right.
So we've built a whole project in Django, we've digitized our Word or PDF, CS, CV or resume, and we've put it online.
So you would make this website, you put it into production, and then you'll be able to send that link to an employer that will help you stand out in a crowd.
And the good thing is, because we've used Django, we are able to use the built in admin page and we are able to create, read, update and delete all elements of the resume, so you never have to change the source code.
Now that that is fantastic, right? So let me change it so you can actually see me again.
Okay, so that that is really, really good.
I have really enjoyed putting this video together.
Again, my name is Bobby Stearman, and I am from did coding.
Please subscribe to my channel.
I do videos like this all of the time.
Before I close the video off, I just like to say thank you to my colleague, James Granger, who helped me put this template together, he designed it and without him we wouldn't be able to give it away for free.
Again, it can be found on my GitHub, which is github.com/bobby-decoding/decoding_resume_templatethankyouverymuchforwatchingihaveenjoyedcreatingitihope.
It's useful, and I'll see you in the next video.