Django Model ForeignKey - django

If I want to add a Foreignkey to a model from another class in the same model e.g.
class1 (models.Model):
variable1 = models.IntegerField()
class2 (models.Model):
variable2 = models.CharField()
foreignkey = models.Foreignkey(class1.variable1)
Is that possible?
Does that make sense as a programming move?
This ForeignKey would be an ID Number (like a primary key) that I would like to import to other classes as well.
# Manoj Govindan:
e.g.
class author(models.Model):
authorlabel= models.IntegerField() # With choices
...
class books(models.Model):
books=models.CharField()
foreignkey= models.Foreignkey(author.authorlabel)
So that I have that data available in that table(?)/model as well.
Thanks!

Perhaps this is what you are looking for:
models.ForeignKey(class1, to_field = 'variable1')
Relevant documentation is here.
This ForeignKey would be an ID Number (like a primary key) that I would like to import to other classes as well.
Not sure what you mean by this. Can you rephrase it and add an example?

Addition to Manoj Govindan's answer...
This ForeignKey would be an ID Number (like a primary key) that I would like to import to other classes as well.
No it do not have to be a number, it can be a string, a datetime value or something else... But it have to be unique.

Related

Find reverse ForeignKey instances of Queryset?

The django documentation is pretty clear on how to look up fields on single instances but what about reverse relationship QuerySet objects.
Example:
class Author(models.Model)
name = models.Charfield(...)
class Book(models.Model)
title = models.Charfield(...)
author = models.ForeignKey(Author, ...)
I now create a queryset object:
special_books = Book.objects.filter(title__icontains="Space")
Now, I want to find all authors that belong to special_books. I want to do something like this:
special_books.authors.all()
Without doing this:
authors = []
for book in special_books:
authors += book.author
Is there a way to do this easily?
Use the referenced Model name (Book in lowercase) to make your query:
Author.objects.filter(book__title__icontains="Space")
If you have a related_name defined in your foreignKey :
class Book(models.Model)
title = models.Charfield(...)
author = models.ForeignKey(Author, related_name="books")
Your queryset would be :
Author.objects.filter(books__title__icontains="Space")
Quoting Django's documentation :
Related managers support field lookups as well. The API automatically follows relationships as far as you need. Use double underscores to separate relationships. This works as many levels deep as you want.
Simply do the lookup on Author model that spans relationship
Author.objects.filter(book__title__icontains="Space")

django model with foreign key to one of two possible models

I have a two models that are similar, but not exactly the same. Here's the best abstraction of the problem that I can come up with.
class Cat(models.Model):
name = models.TextField()
breed = models.TextField()
class Dog(models.Model):
name = models.TextField()
color = models.TextField()
And now I need to make another model like this.
class Pet(models.Model):
favoriteFood = models.TextField()
isCat = models.BooleanField()
animal = models.ForeignKey(?????????)
My problem is that the animal field of the Pet model is going to be a foreign key to either the Cat or the Dog model depending on the value of isCat. How can I do that?
Now, I know this is an unusual/awkward schema in the first place, but I wasn't involved in its creation and I can't change it. I just have to support it. I'm writing these models for an existing database.
You should see Generic relations.
Generic relations is a direct answer.
Another option for this use case is: django-polymorphic :)

ForeignKey to multiple Models or Queryset

It is possible to make a ForeignKey to more than one model. I want to choose from different models like Parts and Machines Model.
I read this to combine multiple models into one list: How to combine 2 or more querysets in a Django view?
How can I get foreign key to that list somehow?
I know that you asked this over year ago, but I had a similar problem and I want to share a link to the solution for future readers.
Generally the contenttypes framework solves this problem, and I guess this is what Daniel Roseman was talking about.
How to use dynamic foreignkey in Django?
You need generic relations.
A generic relation allows you to dynamically the target model of the foreign key.
I'll provide a comprehensive answer for this question, I know its quite old, but it's still relevant.
We're gonna be using Generic Relations.
First, in settings.py make sure that django.contrib.contenttypes is included in the INSTALLED_APPS array.
Let's create a new model in models.py:
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
With content_type we can associate Image with any other model class, while object_id will hold the other model instance.
class Image(models.Model):
image = models.ImageField(
upload_to="imgs/products", blank=True)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
To refer back to the Image model from a Company instance we need to make a reverse generic relation
class Company(models.Model):
name = models.CharField(max_length=100)
images = GenericRelation(Image)
In schema.py, we can create Images in a Company instance like:
company_instance = Company(name="Apple")
company_instance.save()
for img in imgs:
#Image(image=img, content_object=company_instance)
company_instance.images.create(image=img)
company_instance.images.all() # fetch all images
the company_instance.images field is just a GenericRelatedObjectManager (docs)
This is how the final Image table looks in the database:
The Django-polymorphic library provides a simple solution that should work well with the admin and forms too using formsets.
For example:
from polymorphic.models import PolymorphicModel
class BookOwner(PolymorphicModel):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
class StaffBookOwner(BookOwner):
owner = models.ForeignKey(Staff, on_delete=models.CASCADE)
class StudentBookOwner(BookOwner):
owner = models.ForeignKey(Student, on_delete=models.CASCADE)
With this, you can use the parent model to set the owner to either a Staff or Student instance or use the child models directly.

Django Model ForeignKey 2

I dont understand how I can "import"(I dont know the right terminology, so please dont crucify me on this) a Foreignkey from 1 model class to a another:
e.g.
class1 (models.Model):
variable1 = models.CharField()
variable2 = models.CharField()
class2 (models.Model):
variable3 = models.CharField()
variable4 = class1.variable1 "imported" from class1
So now I have all the data from variable1 from class1 available in class2.
I assume this would be accomplished by a ForeignKey.
If I take the example of the official Django documentation (see below), I dont get my answer because:
Why does it only mention the other model and not the variable I create from it.
This would be for a future model, where I dont know the fields yet. But i know the fields already. Again no variable, just the model.
This would be what I am looking for. But this is "imported" from another app. But with me it is in the same app.
ad 1.
class ForeignKey(othermodel[, **options])ΒΆ
ad 2.
class Car(models.Model):
manufacturer = models.ForeignKey('Manufacturer')
# ...
class Manufacturer(models.Model):
# ...
ad 3.
class Car(models.Model):
manufacturer = models.ForeignKey('production.Manufacturer')
Thanks!
If I understand your question correctly.
You are establishing the relationship to the whole model with a foreign key, not just one field, so you will have access to all the fields, even if you only want one.
variable4 = models.ForeignKey(class1)
now you can say variable4.variable1 or variable4__variable2 in a queryset.
Re point 2 - use variable4 = models.ForeignKey('class1') if class1 not already defined
Re point 3 - no need to add application if model in the current application.

What's the most efficient way to retrieve objects of many-to-many relationships?

I have the following two models
class Author(Model):
name = CharField()
class Publication(Model):
title = CharField()
And I use an intermediary table to keep track of the list of authors. The ordering of authors matter; and that's why I don't use Django's ManyToManyField.
class PubAuthor(Model):
author = models.ForeignKey(Author)
pubentry = models.ForeignKey(Publication)
position = models.IntegerField(max_length=3)
The problem is, given a publication, what's the most efficient way to get all authors for the publication?
I can use pubentry.pubauthor_set.select_related().order_by('position'), but then it this will generate one query each time I access the author's name.
I've found out the answer.
In publications:
def authors(self):
return Author.objects.all().filter(
pubauthor__pubentry__id=self.id).order_by('pubauthor__position')