ForeignKey to a Model field?
Asked Answered
P

2

8

I want a foreign key relation in my model with the username field in the User table(that stores the user created with django.contrib.auth.forms.UserCreationForm).

This how my model looks:

class Blog(models.Model):
    username = models.CharField(max_length=200) // this should be a foreign key
    blog_title = models.CharField(max_length=200)
    blog_content = models.TextField()

The username field should be the foreign key.The Foreign Key should be with this field

Parachute answered 19/1, 2016 at 11:5 Comment(0)
S
12

You can't have an ForeignKey to a field, but you can to a row.

You want username which is available through the User model

So:

blog.user.username

If you insist on having blog.username you can define a property like this:

from django.db import models
from django.contrib.auth.models import User

class Blog(models.Model):
    user = models.ForeignKey(User)

Then to access the field you want use:

blog.user.username

If you insist on having blog.username you can define a property like this:

from django.db import models
from django.contrib.auth.models import User

class Blog(models.Model):
    user = models.ForeignKey(User)

    @property
    def username(self):
        return self.user.username

With that property, you can access username through blog.username.

Note on how to import User

user = ForeignKey('auth.User')

or

from django.contrib.auth.models import User
user = ForeignKey(User)

or the more recommended

from django.conf import settings
user = ForeignKey(settings.AUTH_USER_MODEL)
Sinusoidal answered 19/1, 2016 at 11:8 Comment(8)
exactly what I wanted.Parachute
can you tell me whether I also have to import any classes here.Parachute
Model and ForeignKey are from Django's models that you already have imported, and the property decorator is built-in in Python so no.Sinusoidal
is User a model created by me. if so then its not what i was looking for.Parachute
It can be from Django or your own custom User model (in which case you can use settings.AUTH_USER_MODEL to refer to it)Sinusoidal
ok thanks but can you tell me the difference in these three. or what do I search in google to know them.Parachute
contrib not contirb, had a mistake typo in there and will update answer to use that, one secSinusoidal
Given thtat I think you are a beginner, please don't forget that you need to reset or migrate the database too, to put the new changes to your model: docs.djangoproject.com/en/1.9/topics/migrationsSinusoidal
C
22

Unless I'm missing something, you can have a ForeignKey to a specific field:

class Blog(models.Model):
    username = models.ForeignKey(User, to_field='username')

https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.ForeignKey.to_field

Column answered 21/3, 2017 at 17:32 Comment(3)
... except the field in "to_field" has to be unique in the table. So it doesn't work in general.Offen
@CS How does the uniqueness constraint "doesn't work in general"? Take note that the question is on "ForeignKey to a Model field" and as we know, it really has to be unique because that is what a ForeignKey is, a "many-to-one relationship", meaning "many" records from the Blog table relate to "one" record from the User table. If the relating-field (username) is not unique and say there are 3 records with the same value (e.g. John123), then it would not be possible to relate a Blog to User as there are more than 1 record from User with the same field value (for username) to choose from.Becki
@nponcian you are explaining my point more verbosely than I did, so thanks for that. Hopefully it will clarify things for other readers.Offen
S
12

You can't have an ForeignKey to a field, but you can to a row.

You want username which is available through the User model

So:

blog.user.username

If you insist on having blog.username you can define a property like this:

from django.db import models
from django.contrib.auth.models import User

class Blog(models.Model):
    user = models.ForeignKey(User)

Then to access the field you want use:

blog.user.username

If you insist on having blog.username you can define a property like this:

from django.db import models
from django.contrib.auth.models import User

class Blog(models.Model):
    user = models.ForeignKey(User)

    @property
    def username(self):
        return self.user.username

With that property, you can access username through blog.username.

Note on how to import User

user = ForeignKey('auth.User')

or

from django.contrib.auth.models import User
user = ForeignKey(User)

or the more recommended

from django.conf import settings
user = ForeignKey(settings.AUTH_USER_MODEL)
Sinusoidal answered 19/1, 2016 at 11:8 Comment(8)
exactly what I wanted.Parachute
can you tell me whether I also have to import any classes here.Parachute
Model and ForeignKey are from Django's models that you already have imported, and the property decorator is built-in in Python so no.Sinusoidal
is User a model created by me. if so then its not what i was looking for.Parachute
It can be from Django or your own custom User model (in which case you can use settings.AUTH_USER_MODEL to refer to it)Sinusoidal
ok thanks but can you tell me the difference in these three. or what do I search in google to know them.Parachute
contrib not contirb, had a mistake typo in there and will update answer to use that, one secSinusoidal
Given thtat I think you are a beginner, please don't forget that you need to reset or migrate the database too, to put the new changes to your model: docs.djangoproject.com/en/1.9/topics/migrationsSinusoidal

© 2022 - 2024 — McMap. All rights reserved.