Django 1 to Django 2 on_delete error

后端 未结 2 1112
予麋鹿
予麋鹿 2021-01-24 12:46

I believe this workflow was created for a previous Django version. Now when I am trying to upgrade it I get an error to add on_delete. Here is what I have done but it is still n

相关标签:
2条回答
  • 2021-01-24 13:13

    There is a workaround for this.

    If you have lots and lots of table which needs adding "on_delete" parameter where ever Foreign-key or One-to-One key is used.. then going through all the models to add on_delete parameter would be very hectic. You can perform monkey-patch of foreign key to achieve your goal.

    add the below monkey patch file in your project settings folder:

    monkey_patches.py

    from django.db import models
    from django.db.models import ForeignKey
    from django.db import models
    from django.db.models import ForeignKey, OneToOneRel
    from django.db.models.fields.related_descriptors import ReverseOneToOneDescriptor, ForwardOneToOneDescriptor
    from django.utils.translation import gettext_lazy as _
    
    
    class ForeignKeyMonkeyPatch(ForeignKey):
        def __init__(self, to, on_delete=None, *args, **kwargs):
            super().__init__(to, on_delete, *args, **kwargs)
    
    
    class OneToOneFieldMonkeyPatch(ForeignKeyMonkeyPatch):
        many_to_many = False
        many_to_one = False
        one_to_many = False
        one_to_one = True
    
        related_accessor_class = ReverseOneToOneDescriptor
        forward_related_accessor_class = ForwardOneToOneDescriptor
        rel_class = OneToOneRel
    
        description = _("One-to-one relationship")
    
        def __init__(self, to, on_delete=None, *args, **kwargs):
            kwargs['unique'] = True
            super().__init__(to, on_delete, *args, **kwargs)
    
        def deconstruct(self):
            name, path, args, kwargs = super().deconstruct()
            if "unique" in kwargs:
                del kwargs['unique']
            return name, path, args, kwargs
    
        def formfield(self, **kwargs):
            if self.remote_field.parent_link:
                return None
            return super().formfield(**kwargs)
    
        def save_form_data(self, instance, data):
            if isinstance(data, self.remote_field.model):
                setattr(instance, self.name, data)
            else:
                setattr(instance, self.attname, data)
    
        def _check_unique(self, **kwargs):
            # Override ForeignKey since check isn't applicable here.
            return []
    
    
    
    
    setattr(models, 'ForeignKey', ForeignKeyMonkeyPatch)
    setattr(models, 'OneToOneField', OneToOneFieldMonkeyPatch)
    

    Now, call this file in your project settings...

    from .monkey_patches import *

    The above code will reset the ForeignKey and OneToOneField with our monkey-patched classes, thereby setting on_delete as None by default

    P.S. (you can even create an app (named "monkey_patches" or anything that you desire..) and add the above code in models.py)

    0 讨论(0)
  • 2021-01-24 13:29

    According to the Django 2.0 docs (and also the release notes) all Foreignkey fields now have a required on_delete parameter.

    It seems to be missing on your model's fields. The release notes also advise to take a look at your migrations:

    The on_delete argument for ForeignKey and OneToOneField is now required in models and migrations. Consider squashing migrations so that you have fewer of them to update.

    0 讨论(0)
提交回复
热议问题