Как вставить данные в определенную категорию, если она не определена в поле модели Django?
У меня есть проект Django, в котором я создал две модели: Category
и Shop
. Каждый магазин может иметь только одну категорию. Если я не определил категорию магазина, я хочу, чтобы она была в секции Without category
в шаблоне. Как мне установить значение по умолчанию?
Мои модели:
class Category(models.Model):
name = models.CharField(max_length=100)
position = models.IntegerField(unique=True)
def __str__(self):
return f'{self.name}'
class DemoShop(models.Model):
title = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE,
related_name='Cat')
def __str__(self):
return f"{self.title}"
Когда я пишу:
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='Cat', default='Without category')
Это не имеет никакого эффекта в моей базе данных и не отображается в разделе Without category
в моем шаблоне. Если я не поместил магазин в определенную категорию, я хочу, чтобы он отображался в Without category
на странице, например:
Products:
-lorem;
-testshop;
Watch:
-keram;
-pollop;
Without category:
(All shop what I haven't define a category in DB)
Значением по умолчанию для поля модели ForeignKey
является первичный ключ экземпляра модели, на который оно ссылается (если только вы не установите to_field
в вашем ForeignKey значение, указывающее на какое-то другое поле ссылающейся модели).
Обратитесь к https://docs.djangoproject.com/en/4.1/ref/models/fields/#django.db.models.Field.default
Если вы хотите установить для DemoShop
категорию по умолчанию "Без значения", вы можете создать метод класса, который создает/возвращает, если существует Category
с именем "Без категории" (я произвольно выбрал значение аргумента position=5
для метода get_or_create
):
class Category(models.Model):
name = models.CharField(max_length=100)
position = models.IntegerField(unique=True)
def __str__(self):
return f'{self.name}'
@classmethod
def get_default_pk(cls):
obj, created = cls.objects.get_or_create(
name="Without category",
position=5
)
return obj.pk
Затем вы можете использовать определенный classmethod для получения вашей фиктивной категории с именем "Без категории" (при условии, что модели Category
и DemoShop
определены в одном файле models.py:
class DemoShop(models.Model):
title = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE,
related_name='Cat', default=Category.get_default_pk())
Если по какой-то причине вы действительно не можете/не хотите вставлять фиктивную категорию с именем "Без категории" в вашу базу данных, вы можете установить поле category в вашей модели DemoShop
, чтобы оно допускало пустой ввод и было nullable, а затем определить пользовательский метод как getter для связанного имени категории:
class DemoShop(models.Model):
title = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE,
related_name='Cat', blank=True, null=True)
def __str__(self):
return f"{self.title}"
def get_category_name(self):
if self.category is None:
return "Without category"
return self.category.name
Затем используйте этот метод в своем шаблоне, чтобы получить название категории для экземпляров DemoShop.