6

I have the below in my models.py file:

class Film(models.Model):
    title = models.CharField(max_length=200)
    director = models.CharField(max_length=200)
    description = models.CharField(max_length=200)
    pub_date = models.DateField('date published')

class Comment(models.Model):
    film = models.ForeignKey(Film, on_delete=models.CASCADE)
    body = models.CharField(max_length=200)

When I logged into Django admin I added some films, and then added some comments, selecting which film object the comment related to. I then created a couple of users via the admin panel also.

I would like my relationships to be:

Film can have many comments / Comments belong to film

User can have many comments / Comments belong to user

I think, like with comments and films, I just need to define user as a foreign key to comment. I am struggling to do this. I am working through the Django tutorials but I can't see the tutorials covering how I can link other tables to the user.

I thought I would be able to do something like this:

user = models.ForeignKey(User, on_delete=models.CASCADE)

While importing User like this:

from django.contrib.auth.models import User

The result at the moment is if I keep user = models.ForeignKey(User, on_delete=models.CASCADE) I get err_connection_refused

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Dan
  • 951
  • 1
  • 23
  • 46
  • You can see this question [link](https://stackoverflow.com/questions/34305805/django-foreignkeyuser-in-models) , maybe it can help you. – Carlos Fernández Jan 25 '18 at 00:57
  • `err_connection_refused` errors are unrelated to foreign keys. It means Django wasn't able to connect to the database. – kichik Jan 25 '18 at 00:58
  • 1
    Have you changed your default user model in the settings? instead of using User directly in the Foreign key, you should use `user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)` – Angel F Jan 25 '18 at 01:04
  • @kichik I had some indentation errors to fix. Thank you – Dan Jan 25 '18 at 01:18
  • @AngelF Adding that along with `from django.conf import settings` helped. However when I try to add a new comment while selecting the film and user the new comment relates to, I get "table films_comment has no column named user_id". Do I need to add this to models.py like I have `Film` and `Comment`? Or is my current code not sufficient? I thought I had defined this under `class Comment` – Dan Jan 25 '18 at 01:20
  • Just at this moment, if you have the class as in your question (without user field in `Film` model and haven't not already added the relation, you will et this error, add the relation, make migrations, then all should be ok – Angel F Jan 25 '18 at 01:30
  • Just to be clear though, the user is not able to add a film. Only a comment. And it is the comment which is related to both the user and the film. Can you clarify your response please, not sure I understand. Thank you! – Dan Jan 25 '18 at 01:35
  • when i try to do makemigrations I get "You are trying to add a non-nullable field 'user' to comment without a default" – Dan Jan 25 '18 at 02:28
  • @Dan i have added an answer, i hope that it can help you to solve your issues – Angel F Jan 25 '18 at 02:46

2 Answers2

9

Maybe have you changed your default user model in the settings?

Instead of using User directly with the the Foreign key, you should use user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) in your Comment Model, as follow

class Comment(models.Model):
    film = models.ForeignKey(Film, on_delete=models.CASCADE)
    body = models.CharField(max_length=200)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

You need to apply migrations to be able to add user to Comment, python manage.py makemigrations python manage.py migrate

if at the moment that you are applying migrations, shell shows a message telling You are trying to add a non-nullable field 'user' to comment without a default

You have 2 Options

  1. Skip migrations and add a default value to the field in the models or set the attribute as nullable, whatever else that you need ie

user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)

and apply migrations again

  1. Or select a default value to the new field, should be an id of an existing user in databse

This is because django should populate existing records in database, if exist

Angel F
  • 479
  • 3
  • 13
3

Use "settings.AUTH_USER_MODEL".

So, import "settings" from "django.conf", then use "settings.AUTH_USER_MODEL" as shown below:

from django.db import models
from django.conf import settings # Here

class Comment(models.Model):
    film = models.ForeignKey(Film, on_delete=models.CASCADE)
    body = models.CharField(max_length=200)
                            # Here
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129