Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Django Models

In this lesson, you’re going to start looking at databases and Django models. When you created your app before, you created a file called models.py. The models are where you do the database interactions.

This is what a Django model looks like:

# Create your models here.
class Project(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    technology = models.CharField(max_length=20)
    image = models.FilePathField(path='/img/')

Comments & Discussion

Pygator on Oct. 13, 2019

I get what you’re saying about the ORM, but how can you have a class defined without any mention of “self” . Really interesting !

Martin Breuss RP Team on Oct. 16, 2019

There’s a lot going on under the hood, and I’m myself far from familiar with the whole Django source code. Good thing is that it isn’t necessary in order to get started building something–and great thing about Open Source is that you can always keep diving deeper into it, if you want to :)

But the important part here that makes this possible, is that all Django models you’ll define inherit from models.Model. A lot of logic is taken care of in there, which allows us to use a class in this unfamiliar way, without needing to define an __init__() method or use self at all.

Kevin Lao on Nov. 19, 2019

Hi Martin,

You probably will be hitting this topic somewhere down the line, but just in case I wanted to place this question somewhere. Let’s say for example, we currently have: class Project(models.Model): title = models.CharField(max_length = 100)

and for some business reason we want to get change the number of characters in the title fields. I’d normally assume that we would change the number of max characters, but in reality there are already customers who have 100 characters maximum for their titles. Is there a way for us to handle a situation to where say, we were to change the title max_length = 60 without doing damage to the database?

Martin Breuss RP Team on Nov. 23, 2019

It depends what you want to achieve. I think that Django enforces the max_length on the Python side, so changing this and propagating the changes with a database migration will ensure that all subsequent entries will be limited to only 60 characters.

If you would want to apply the character limit also to existing entries that have more than 60 chars, you’d have to decide what to do with the extra chars. You could e.g. write a script that truncates the existing entries.

I’d suggest you to look into our series of articles on Django Migrations, starting with Django Migrations: A Primer to dive deeper.

R morel on May 4, 2020

cool man

MrUzo on May 22, 2020

Hey Martin, I’m building a modified model, but i’m getting this error message: “users.models.Friend.DoesNotExist: Friend matching query does not exist” Hi everyone, i’m trying to build a django model that enables users to connect with each other, but I get the above error when I try to render the list of connected users.

My model:

#for users to have a profile image
class Profile(models.Model):
    user = models.OneToOneField(User, ondelete=models.CASCADE)
    image = models.ImageField(default='default.jpg', uploadto='profilepics')
    def str(self):
        return f'@{self.user.username}'
    def save(self, args, kwargs):
        super().save()
        img = Image.open(self.image.path)
        if img.height > 300 or img.width > 300:
            outputsize = (300, 300)
            img.thumbnail(outputsize)
            img.save(self.image.path)
#for users to be able to connect with eachother
class Friend(models.Model):
    connect = models.ManyToManyField(User)
    currentuser = models.ForeignKey(User, relatedname='owner', null=True, ondelete=models.DONOTHING)
    @classmethod
    def makefriend(cls, currentuser, newfriend):
        friend, created = cls.objects.getorcreate(
            currentuser=currentuser
        )
        friend.connect.add(newfriend)
    @classmethod
    def losefriend(cls, currentuser, newfriend):
        friend, created = cls.objects.getorcreate(
            currentuser=currentuser
        )
        friend.connect.remove(newfriend)
```*

View that lists the connected friends:

def profile(request): posts = request.user.author.all users = User.objects.exclude(id=request.user.id) friend = Friend.objects.get(current_user=request.user.friend_set.instance.id) friends = friend.connect.all() context = { ‘posts’: posts, ‘users’: users, ‘friends’: friends } return render(request, ‘users/profile.html’, context) ```* Any help is appreciated. Thanks

Martin Breuss RP Team on May 23, 2020

Hi @MrUzo and awesome that you’re expanding on the project and building out your own implementation 👍

Your Code

The second part of your code got wrongly formatted, let me know if this is what you have:

def profile(request):
    posts = request.user.author.all
    users = User.objects.exclude(id=request.user.id)
    friend = Friend.objects.get(current_user=request.user.friend_set.instance.id)
    friends = friend.connect.all()
    context = { 'posts': posts, 'users': users, 'friends': friends }
    return render(request, 'users/profile.html', context)

It might be easier if you share a GitHub repository, since there is some logic that you’re using that isn’t explained in the code you shared (e.g. how does your User model look like? Did you change it? You are requesting posts through the user object, and it seems you have an author attribute that isn’t part of the default Django User model, etc.)

Possible Errors

Here are some thoughts on what you can try out:

  • I think that this: posts = request.user.author.all is missing the brackets for your method call on .all()
  • Not sure what you’re doing with the .friend_set.instance.id part of that call. Your Friend model doesn’t seem to have an instance attribute
  • Double-check (and maybe explain here) your logic of what you want to fetch with this call:
    • Friend.objects.get() is gonna return one instance, but you’re accessing that instance through the friend_set of the current user (which can have multiple friends)
    • Then you are getting all connected friends of that friend. Who is that first friend? Is it meant to be the current user? (If so, there are more direct ways of getting to their friends) Who else is it meant to refer to?

I hope these suggestions can help you on the way, but as I mentioned, there’s some code missing to be able to get the full picture. All the best and keep up the great work :)

Scretch on June 17, 2020

Hello Martin,

I’m expanding the capabilities of my build from this tutorial and I was wanting to add an additional class object(if thats what i need) to the models file. The goal is to have a button or just the text of a link on each project page so I can link to projects I’m hosting elsewhere with heroku etc. I am currently able to add the neccessary HTML to have a link appear in detail.html but that same link shows up in each project now. Ideally it would be nice to have that field appear in the admin page with title, description, technology, and img so I can just paste a link on there.

Thanks. Im off to django docs to see if I missed something

Scretch on June 17, 2020

Ah, I did miss it. If anyone else is trying something similar. The model field is URLField. I found more details here:

www.geeksforgeeks.org/urlfield-django-models/https://docs.djangoproject.com/en/3.0/ref/models/fields/

Tell me if I gave bad info please! I want to be sure I’m contributing to this great tutorial.

Martin Breuss RP Team on June 18, 2020

Hi @Scretch! Yes, you can add info fields to your models any time, just remember to run your two migration commands afterwards to propagate your model changes to your database structure.

As to which is the best field to use, I think you made the right choice with Django’s URLField. As it explains in the docs, it’s just a CharField with some URL-specific validation methods added. A URL is just some text, so any field that holds text can work for this, but sounds like a good idea to use what Django specifically suggests for URLs.

Become a Member to join the conversation.