Can we define models.CASCADE only without using on_delete?

Viewed 86

As I know is that when we defining foreign key in django we can set like on_delete=models.CASCADE.

Recently I have seen code like content_type = models.ForeignKey(ContentType,models.CASCADE).

My question is that does django allow to define models.CASCADE without using on_delete ? OR if we define like above does it work differently?

content_type = models.ForeignKey(
        ContentType,
        models.CASCADE,
        verbose_name=_('content type'),        
    )
2 Answers

Yes, we can do that.


To clearly understand it, try to understand the below code:

def fn(x, y, z=0):
    print('x =', x, 'y =', y, 'z =', z)


fn(1, 2)           # Prints: x = 1 y = 2 z = 0
fn(1, 2, 3)        # Prints: x = 1 y = 2 z = 3
fn(1, y=2)         # Prints: x = 1 y = 2 z = 0
fn(1, y=2, z=3)    # Prints: x = 1 y = 2 z = 3
fn(x=1, y=2)       # Prints: x = 1 y = 2 z = 0
fn(x=1, y=2, z=3)  # Prints: x = 1 y = 2 z = 3
fn(y=2, z=3, x=1)  # Prints: x = 1 y = 2 z = 3

Now, have a look at the source code of ForeignKey. It looks something like this:

class ForeignKey(ForeignObject):
    ...
    def __init__(
        self, to, on_delete, 
        related_name=None, related_query_name=None,
        limit_choices_to=None, parent_link=False, 
        to_field=None, db_constraint=True, **kwargs,
    ):
        ...

So, when we write:

content_type = models.ForeignKey(
    ContentType,
    models.CASCADE,
    verbose_name=_('content type'),        
)

The parameter to will be ContentType and the parameter on_delete will be models.CASCADE.

This is exactly same as writing:

content_type = models.ForeignKey(
    on=ContentType,
    on_delete=models.CASCADE,
    verbose_name=_('content type'),        
)

Defining the Foreign key without writing on_delete should work, because the second parameter of the __init__ or the ForeignKey is on delete, see below:

def __init__(self, to, on_delete, related_name=None, related_query_name=None,
                 limit_choices_to=None, parent_link=False, to_field=None,
                 db_constraint=True, **kwargs):

Here is the line on Github.

Specifying the key name "on_delete" removes the need to have the arguments in order, but as it is the second argument it would work both ways.

but for example, if you were to need db_constraint, this would need to be specified with a keyName, or provide all the other arguments in between as well, using the key name in this case would make it easier and not be in order.

Related