2

I need a BaseCommand that deletes entries from the specified model in the parameters.

Run this: ./manage.py delete_data_model app.shop

# delete_data_model.py

from django.core.management.base import BaseCommand, CommandError
from django.db.transaction import atomic


class Command(BaseCommand):
    help = "Deleted data from model"

    def add_arguments(self, parser):
        parser.add_argument('model', required=True, type=str)

    def handle(self, *args, **options):
        self.stdout.write("Begin")
        with atomic(using='default'):
            try:
                path = options['model']
                app, model = path.split('.')[:2]
                from (app) import (model) as Model  # ??? how do this
                Model.objects.all().delete()
            except Exception as e:
                raise CommandError("Error {}".format(e))
        self.stdout.write("Complete")

I expect empty table Shop.

2 Answers2

2

Try this

from django.core.management.base import BaseCommand, CommandError
from django.db.transaction import atomic
from django.apps import apps


class Command(BaseCommand):
    help = "Deleted data from model"

    def add_arguments(self, parser):
        parser.add_argument('model', required=True, type=str)

    def handle(self, *args, **options):
        self.stdout.write("Begin")
        with atomic(using='default'):
            try:
                path = options['model']
                app, model = path.split('.')[:2]
                Model = apps.get_model(app_label=app, model_name=model)
                Model.objects.all().delete()
            except Exception as e:
                raise CommandError("Error {}".format(e))
        self.stdout.write("Complete")

Refs :
1. Django: Get model from string?
2. apps.get_model(app_label, model_name, require_ready=True) -- Django Doc

JPG
  • 82,442
  • 19
  • 127
  • 206
1

What you require is get_model. You can get the model from the model name specified using get_model. For example:

For Django < 1.9:

from django.db.models.loading import get_model

mymodel = get_model('app_name', 'model_name') 

So you can change the method as:

def handle(self, *args, **options):
    self.stdout.write("Begin")
    with atomic(using='default'):
        try:
            path = options['model']
            app, model = path.split('.')[:2]
            mymodel = get_model(app, model) <--get model from string argument
            mymodel.objects.all().delete()
        except Exception as e:
            raise CommandError("Error {}".format(e))
    self.stdout.write("Complete")

For Django >= 1.9:

from django.apps import apps

mymodel = apps.get_model('app_name', 'model_name') 

So you can change the method as:

def handle(self, *args, **options):
    self.stdout.write("Begin")
    with atomic(using='default'):
        try:
            path = options['model']
            app, model = path.split('.')[:2]
            mymodel = apps.get_model(app, model) <--get model from string argument
            mymodel.objects.all().delete()
        except Exception as e:
            raise CommandError("Error {}".format(e))
    self.stdout.write("Complete")
Sanip
  • 1,772
  • 1
  • 14
  • 29
  • 1
    `django.db.models` have not `get_model` method, need: `from django.apps import apps model = apps.get_model('app.model')` – Aleksandr Shustrov Apr 17 '19 at 09:54
  • Oh yes, I did not realize that it was depreciated after 1.9. Thank you for the suggestion. – Sanip Apr 17 '19 at 10:04
  • Hm, i test it on django **1.11** and django **2.2** so both case not working :( While try `from django.db.models import get_model` ofc – Aleksandr Shustrov Apr 17 '19 at 10:27
  • Well currently I am using django 1.8 in my project where I have used `django.db.models import get_model` and all goes fine for me. – Sanip Apr 17 '19 at 10:34
  • Does it give you `AppRegistryNotReady` exception while using in **django 1.11**? – Sanip Apr 17 '19 at 10:39
  • I have updated my answer. So it should be `from django.db.models.loading import get_model` instead of `from django.db.models import get_model`. Hope it helps you. – Sanip Apr 17 '19 at 10:44
  • I already chose solution with `from django.apps import apps`, but I checked `loading` module and this module is not in django 1.11 too. – Aleksandr Shustrov Apr 17 '19 at 10:51
  • Maybe 1.11 so old and 2.2 so new? ) – Aleksandr Shustrov Apr 17 '19 at 10:53
  • Going through the django 1.11 release notes(https://docs.djangoproject.com/en/2.2/releases/1.11/#miscellaneous), it says you need to set the `require_ready` to **False**. – Sanip Apr 17 '19 at 10:55
  • https://docs.djangoproject.com/en/2.2/ref/applications/#django.apps.AppConfig.get_model this link shows how to set the `require_ready` to False. – Sanip Apr 17 '19 at 10:56