Djnago,是否可以用一个模型创建多个状态选择?

这是我的实际情况 models.py我想让我可以创建一个多选的状态。

class Status(models.Model):
      slug = models.SlugField(unique=True)
      category = models.TextField()


class Example(models.Model):
      category= models.ForeignKey(Status)

我想有可能添加一个子类别。换句话说,如果我在我的网站上创建一个新的类别 “产品”。status model我想有可能创建子类别选择,从类别中选择,并在我的示例模型中选择一个新的字段sub_category。

例如:使用Status.models,客户可以创建一个产品的类别,例如 “汽车 “和相关的子类别 “轮子”,”方向盘 “等等。之后,当填写Example.models并选择 “Car “类别时,客户端只能选择之前存储的子类别(”whell”, “steering wheel”)。我希望现在我的解释更好

解决方案:

你可以为同一个模型多次设置一个外键,但你需要在其中加入 related_name 参数。

全Python的方式

# models.py

class Status(models.Model):
    slug = models.SlugField(unique=True)
    category = models.TextField()
    # This allows us to have hierarchy of categories.
    parent =  models.ForeignKey(
        "self", 
        null=True,
        blank=True,
        related_name="children", 
        related_query_name="child",
        on_delete=models.PROTECT,
    )


class Example(models.Model):
    category = models.ForeignKey(
        Status, 
        related_name="example_categories",
        limit_choices_to={'parent': None},
    )
    # This field is hidden on new objects.
    sub_category = models.ForeignKey(
        Status,
        related_name="example_sub_categories",
        null=True,
        blank=True,
    )
# forms.py

class ExampleForm(forms.ModelForm):
    class Meta:
        model = Example
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        # When we instantiate the form, we check if the object 'instance' exists.
        # If it does not, we hide the `sub_category` field.
        # Otherwise we restrict the queryset to children of the `category` field.

        # NOTE: this will need to be properly cleaned. It does not prevent editing
        # the parent `category` after the `sub_category` has already been saved.
        instance = kwargs.get('instance')
        if not instance:
            self.fields.get('sub_category').widget = forms.HiddenInput()
        else:
            sub_cateogries = Status.objects.filter(parent=instance.category).all()
            self.fields.get('sub_category').queryset = sub_cateogries

# admin.py

@admin.register(Example)
class ExampleAdmin(admin.ModelAdmin):
    form = ExampleForm

这种方法的缺点是需要保存一次对象,然后才能编辑子类别。这并不理想,因为它给对象管理周期增加了第二步。

更好的方法

比较好的处理方式涉及到的内容比较多,需要一些JS,所以我在这里就不提供代码了。不过,我将解释一下它是什么以及如何做到这一点。

你可以使用Select2来执行AJAX请求到一个自定义的管理视图,该视图以JSON数组的形式返回一个子类别的列表。

添加一个自定义的管理视图非常简单,只需确保选中 user.is_staff 和适当的权限。您可以通过覆盖掉的 get_urls() 在你的 ExampleAdmin 类。类似这样的工作…

def get_urls(self):
    return [
        path(
            "auto_field/", 
            self.admin_site.admin_view(YourView.as_view()), 
            name='example_select2',),
    ] + super().get_urls()

能够做这样的改变是让你的Django更上一层楼的核心。第一种方案可行,但如果可以的话,请选择第二种方案。

给TA打赏
共{{data.count}}人
人已打赏
解决方案

如何基于数据属性(jQuery)获取特定的HTML元素。

2022-5-11 10:00:15

解决方案

如何使用内部区域?

2022-5-11 10:00:17

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索