Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Model set foreign key to a field of another Model

Is there any way to set a foreign key in django to a field of another model?

For example, imagine I have a ValidationRule object. And I want the rule to define what field in another model is to be validated (as well as some other information, such as whether it can be null, a data-type, range, etc.)

Is there a way to store this field-level mapping in django?

like image 716
Cory Avatar asked Apr 08 '09 14:04

Cory


3 Answers

I haven't tried this, but it seems that since Django 1.0 you can do something like:

class Foo(models.Model):
    foo = models.ForeignKey(Bar, to_field='bar')

Documentation for this is here.

like image 143
Monika Sulik Avatar answered Nov 13 '22 02:11

Monika Sulik


Yes and no. The FK relationship is described at the class level, and mirrors the FK association in the database, so you can't add extra information directly in the FK parameter.

Instead, I'd recommend having a string that holds the field name on the other table:

class ValidationRule(models.Model):
    other = models.ForeignKey(OtherModel)
    other_field = models.CharField(max_length=256)

This way, you can obtain the field with:

v = ValidationRule.objects.get(id=1)
field = getattr(v, v.other_field)

Note that if you're using Many-to-Many fields (rather than a One-to-Many), there's built-in support for creating custom intermediary tables to hold meta data with the through option.

like image 18
Jarret Hardie Avatar answered Nov 13 '22 02:11

Jarret Hardie


You need to use "to_field" in "models.ForeignKey()" to set other field in other model:

ForeignKey.to_field

The field on the related object that the relation is to. By default, Django uses the primary key of the related object. If you reference a different field, that field must have unique=True.

For example, as a foreign key, "categories" field in "Product" model references "name" field in "Category" model as shown below. *Be careful, the referenced field "name" in "Category" model needs "unique=True" or "primary_key=True" otherwise there is an error:

# "models.py"

from django.db import models
                                            # "unique=True" or
class Category(models.Model):               # "primary_key=True" are needed 
    name = models.CharField(max_length=100, unique=True)
    
class Product(models.Model):
    name = models.CharField(max_length=100)                
    categories = models.ForeignKey(
        Category, 
        to_field='name', # ← Here
        on_delete=models.PROTECT
    )
like image 1
Kai - Kazuya Ito Avatar answered Nov 13 '22 00:11

Kai - Kazuya Ito