How do you specify a default for a Django ForeignK

2019-01-17 11:47发布

问题:

How can I set a default value on a ForeignKey field in a django Model or AdminModel?

Something like this (but of course this doesn't work)...

created_by = models.ForeignKey(User, default=request.user)

I know I can 'trick' it in the view, but in terms of the AdminModel it doesn't seem possible.

回答1:

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, default=lambda: Foo.objects.get(id=1) )


回答2:

Here's a solution that will work in Django 1.7. Instead of providing the default at the field definition, set it as null-able, but overide the 'save' function to fill it on the first time (while it's null):

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, null=True)

    def save(self, *args, **kwargs):
        if self.a is None:  # Set default reference
            self.a = Foo.objects.get(id=1)
        super(Bar, self).save(*args, **kwargs)


回答3:

For django 1.7 or greater,

Just create an ForeignKey object and save it. "default" value can be the id of the the object that should be linked by default.

For example,

created_by = models.ForeignKey(User, default=1)


回答4:

If you are using the development version of Django, you can implement the formfield_for_foreignkey() method on your AdminModel to set a default value.



回答5:

I've done this similarly to @o_c, but I'd rather use get_or_create than just plain pk.

class UserSettings(models.Model):
    name = models.CharField(max_length=64, unique=True)
    # ... some other fields 

    @staticmethod
    def get_default_user_settings():
        user_settings, created = UserSettings.objects.get_or_create(
            name = 'Default settings'
        )
        return user_settings

class SiteUser(...):
    # ... some other fields

    user_settings = models.ForeignKey(
        to=UserSettings, 
        on_delete=models.SET_NULL, 
        null=True
    )

    def save(self, *args, **kwargs):
        if self.user_settings is None:
            self.user_settings = UserSettings.get_default_params()
        super(SiteUser, self).save(*args, **kwargs)


回答6:

def get_user_default_id():
    return 1

created_by = models.ForeignKey(User, default=get_user_default_id)


回答7:

As for me, for Django 1.7 its work, just pk:

category = models.ForeignKey(Category, editable=False, default=1)

but remember, that migration looks like

migrations.AlterField(
            model_name='item',
            name='category',
            field=models.ForeignKey(default=1, editable=False, to='item.Category'),
            preserve_default=True,
        ),

so, i don't think it's to be working with dynamic user pk.



回答8:

This is a slight modification to the answer from o_c. It should save you one hit on the database. Notice in the save method I use self.a_id = 1 instead of self.a = Foo.objects.get(id=1). It has the same effect without having to query Foo.

class Foo(models.Model):
    a = models.CharField(max_length=42)

class Bar(models.Model):
    b = models.CharField(max_length=42)
    a = models.ForeignKey(Foo, null=True)

    def save(self, *args, **kwargs):
        if self.a is None:  # Set default reference
            self.a_id = 1
        super(Bar, self).save(*args, **kwargs)


回答9:

For Django >= 1.7, you can set the default for a ForeignKey field in two different ways:

1) Directly as an integer

DEFAULT_CREATED_BY_USER = 42

class MyModel(Model):
    created_by = models.ForeignKey(User, default=DEFAULT_CREATED_BY_USER)

2) As a nonlambda callable returning an integer

You can also use a callable that can be resolved to a full module path. This means that lambdas does not work. But this will:

def default_created_by_user():
    return 42

class MyModel(Model):
    created_by = models.ForeignKey(User, default=default_created_by_user)

References:

  • https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey (django docs)
  • https://code.djangoproject.com/ticket/6445 (why lambdas fail)


回答10:

class table1(models.Model):
    id = models.AutoField(primary_key=True)
    agentname = models.CharField(max_length=20)

class table1(models.Model):
    id = models.AutoField(primary_key=True)
    lastname = models.CharField(max_length=20)
    table1 = models.ForeignKey(Property)