Jonathan Chiong
Jonathan Chiong

Reputation: 115

How to use multiple fields from one model to another as foreignkey?

I am trying to use multiple fields from my Dog model as choices in MyDog model. When i create a new MyDog instance, it both shows what is in Dog.name. How can i make MyDog.breed see whats in Dog.breed?

class Dog(models.Model):
name = models.CharField(max_length=10)
breed = models.CharField(max_length=10,unique=True)
def __str__(self):
    return self.name

class MyDog(models.Model):   
    name=models.ForeignKey(Dog,related_name='mydogname',on_delete=models.CASCADE)
    breed = models.ForeignKey(Dog,related_name='mydogbreed',on_delete=models.CASCADE,to_field='breed',db_column='breed')

Upvotes: 0

Views: 32

Answers (2)

dirkgroten
dirkgroten

Reputation: 20672

That's not how ForeignKey relationships work. When you make a relationship, you make a relationship to an object (another table), not to a specific column of that table.

So if myDog = MyDog(name=Dog.objects.first()) creates a MyDog object related to the first Dog in the database, then myDog.name.name will give you the name field of the Dog and myDog.name.breed would give you the breed. As you can see, your models are not well defined this way.

A more logical structure would be:

 class Breed(models.Model):
     name = models.CharField(...)

     def __str__(self):
         return self.name

 class Dog(models.Model):
     name = models.CharField(...)

 class MyDog(models.Model):
     dog = models.ForeignKey(Dog)
     breed = models.ForeignKey(Breed)

 dog = Dog.objects.create(name='Pluto')
 breed = Breed.objects.create(name='Collie')
 my_dog = MyDog(dog=dog, breed=breed)
 my_dog.breed.name  # "Collie"
 print(my_dog.breed)  # "Collie" because of __str__()

Upvotes: 1

Ozgur Akcali
Ozgur Akcali

Reputation: 5482

What is shows there is what you define with

def __str__(self):
    return self.name

which roughly translates to "String representation of a Dog instance". I don't think you can change depending on the ForeignKey field they are used in, but it shouldn't have any effect on functionality, only on how it is displayed. You can print the breed like this if you want:

my_dog = MyDog.objects.get(...)
print my_dog.breed # this prints what __str__ method prints for dog
print my_dog.breed.breed # this prints breed field of dog

Upvotes: 0

Related Questions