Khaled.sahraoui
Khaled.sahraoui

Reputation: 17

Change the foreignKey id to another Field

I don't know if there is a logic for this, because i seen it before when I programed with C# and VB, but in Django, it's seems hard to get it.

So what I want to ? I want the table in database save the name and not the id of the foreignKey. And this is the model.py

from pyexpat import model
from statistics import mode
from venv import create
from django.db import models
from django.contrib.auth.models import User
from django.db.models.base import Model
from django.forms import IntegerField



class Post(models.Model):
    name = models.CharField(max_length=150)

    def __str__(self):
        return str(self.name)


class Person(models.Model):
    post = models.ForeignKey(Post , on_delete=models.CASCADE)
    name = models.CharField(max_length=100, unique=True)

    def __str__(self):
        return f"({self.name} is {self.post})"



class Room(models.Model):
    name = models.CharField(max_length= 150, unique = True)

    def __str__(self):
        return str(self.name)


class Classification(models.Model):
    name = models.ForeignKey(Person, on_delete=models.CASCADE)
    room = models.ForeignKey(Room, on_delete=models.CASCADE)
    date = models.DateField(auto_created=False)
    create_date = models.DateTimeField(auto_created=True)

    def __str__(self):
       return f"({self.name} Take {self.room}  at {self.date})"

The result in Database table:

enter image description here

What I want to see in the database table, is that Django replace the id's in name_id column with names, and room_id with room names

Is that possible?

Upvotes: 1

Views: 1629

Answers (2)

Ayman
Ayman

Reputation: 363

First you need to make the name a Pk in the Model primary_key=True then in the ForeignKey set the to_field='name'

very easy ...

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477794

You can use the to_field=… parameter [Django-doc] to specify to what the ForeignKey should point. This should always be a unique field in the targetting model. So you can use:

class Classification(models.Model):
    person = models.ForeignKey(Person, to_field='name', on_delete=models.CASCADE)
    room = models.ForeignKey(Room, on_delete=models.CASCADE)
    date = models.DateField()
    create_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
       return f'({self.person_id} Take {self.room}  at {self.date})'

You should likely however recreate the migrations for the Classification model, and thus let this create a ForeignKey that references the name of the Person model.

You can here use self.person_id to avoid making an extra query to load the Person object. This will thus improve the efficiency when calling the __str__ method of a Classification object.

Upvotes: 1

Related Questions