You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Django模型未指定分类的店铺设置默认分类显示?

问题

我有一个Django项目,创建了Category和DemoShop两个模型,每个店铺仅对应一个分类。希望未指定分类的店铺在模板中显示在“Without category”区域,尝试设置外键default='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')

该设置在数据库和模板中均无效果,期望页面显示效果如下:

Products:
    -lorem;
    -testshop;
Watch:
    -keram;
    -pollop;
Without category:
    (所有未在数据库中指定分类的店铺)
解决方案

外键的default值不能直接设字符串,它要求关联的是Category模型的实例或主键ID,不是文本内容。以下两种方案可实现需求:

方案一:允许外键为空,模板单独处理无分类店铺

  1. 修改DemoShop模型的category字段,允许为空:
class DemoShop(models.Model):
    title = models.CharField(max_length=100)
    category = models.ForeignKey(
        Category, 
        on_delete=models.CASCADE,
        related_name='shops',  # 建议改成语义化名称,比如shops
        null=True, 
        blank=True
    )

    def __str__(self):
        return f"{self.title}"
  1. 执行数据库迁移:
python manage.py makemigrations
python manage.py migrate
  1. 视图中获取分类和无分类店铺:
from django.shortcuts import render
from .models import Category, DemoShop

def shop_list(request):
    categories = Category.objects.all()
    uncategorized_shops = DemoShop.objects.filter(category__isnull=True)
    return render(request, 'shop_list.html', {
        'categories': categories,
        'uncategorized_shops': uncategorized_shops
    })
  1. 模板渲染:
Products:
{% for shop in categories.get(name='Products').shops.all %}
    -{{ shop.title }};
{% endfor %}

Watch:
{% for shop in categories.get(name='Watch').shops.all %}
    -{{ shop.title }};
{% endfor %}

Without category:
{% for shop in uncategorized_shops %}
    -{{ shop.title }};
{% empty %}
    暂无未分类店铺
{% endfor %}

方案二:创建默认“无分类”实例,设置外键默认值

  1. 生成空迁移文件并添加默认分类创建逻辑:
python manage.py makemigrations --empty your_app_name

打开生成的迁移文件,修改为:

from django.db import migrations

def create_default_category(apps, schema_editor):
    Category = apps.get_model('your_app_name', 'Category')
    # 避免重复创建
    Category.objects.get_or_create(
        name='Without category',
        defaults={'position': 999}  # 选一个不冲突的position值
    )

class Migration(migrations.Migration):
    dependencies = [
        ('your_app_name', '0001_initial'),  # 替换为你的初始迁移文件名
    ]

    operations = [
        migrations.RunPython(create_default_category),
    ]
  1. 执行迁移:
python manage.py migrate
  1. 修改DemoShop模型,设置外键默认值为该分类的ID:
def get_default_category():
    return Category.objects.get(name='Without category').id

class DemoShop(models.Model):
    title = models.CharField(max_length=100)
    category = models.ForeignKey(
        Category, 
        on_delete=models.CASCADE,
        related_name='shops',
        default=get_default_category
    )

    def __str__(self):
        return f"{self.title}"
  1. 再次执行迁移,后续新建店铺未指定分类时会自动关联到“Without category”,模板直接按分类渲染:
{% for category in categories %}
{{ category.name }}:
    {% for shop in category.shops.all %}
    -{{ shop.title }};
    {% endfor %}
{% endfor %}

内容的提问来源于stack exchange,提问作者Beginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 22:30:49