У меня 3 модели (упрощенно):
class Product(models.Model):
category = models.ForeignKey('Category', related_name='products', to_field='category_name')
brand = models.ForeignKey('Brand', related_name='products', to_field='brand_name')
class Brand(models.Model):
brand_name = models.CharField(max_length=50)
categories = models.ManyToManyField('Category', related_name='categories')
class Category(models.Model):
category_name = models.CharField(max_length=128)
Я хочу изменить категорию в админке на несколько продуктов, для этого у меня есть специальная функция админа. После этого мне нужно обновить Brand-Categories
отношение «многие ко многим», чтобы проверить, доступно ли это Category
для определенного Brand
. Я написал эту функцию:
def brand_refresh():
brands = Brand.objects.all().prefetch_related('shops', 'categories')
products = Product.objects.select_related('shop', 'brand', 'category')
for brand in list(brands):
for category in brand.categories.all():
if not products.filter(category=category).exists():
brand.categories.remove(category)
for product in list(products.filter(brand=brand).distinct('category')):
if product.category not in [None, category]:
brand.categories.add(product.category)
Мне кажется, что это monstro работает, но для прохождения всех циклов требуется 2 часа (у меня есть ~ 220 тыс. Продуктов, 4 тыс. Марок + и ~ 500 категорий). У меня есть какой-нибудь лучший способ обновить отношение M2M здесь? Я думаю, что .prefetch_related()
должен помочь здесь, но то, что я сейчас имею, кажется, не имеет никакого эффекта.