How to use django-smart-selects with through model

Hello!

I have three models

class ImagePromptSubcategories(models.Model):
    id = models.BigAutoField(primary_key=True)
    created_at = models.DateTimeField(blank=True, null=True, auto_now_add=True)
    updated_at = models.DateTimeField(blank=True, null=True, auto_now=True)
    deleted_at = models.DateTimeField(blank=True, null=True)
    image_prompt_category = models.ForeignKey(ImagePromptCategories,
                                              models.DO_NOTHING, blank=True,
                                              null=True)
    tag = models.TextField(blank=True, null=True)
    ordering = models.BigIntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'image_prompt_subcategories'

class ImagePrompts(models.Model):
    id = models.BigAutoField(primary_key=True)
    created_at = models.DateTimeField(blank=True, null=True, auto_now_add=True)
    updated_at = models.DateTimeField(blank=True, null=True, auto_now=True)
    deleted_at = models.DateTimeField(blank=True, null=True)
    image_prompt_category = models.ForeignKey(ImagePromptCategories,
                                              models.DO_NOTHING, blank=True,
                                              null=True)
    image_prompt_subcategories = models.ManyToManyField(
        ImagePromptSubcategories,
        through='ImagePromptsSubcategories',
        blank=True
    )
    prompt = models.TextField(blank=True, null=True)
    example_url = models.TextField(blank=True, null=True)
    example_url_thumb = models.TextField(blank=True, null=True)
    prompt_position = models.TextField()
    style_preset = models.TextField(blank=True, null=True)
    icon = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'image_prompts'


class ImagePromptsSubcategories(models.Model):
    id = models.BigAutoField(primary_key=True)
    created_at = models.DateTimeField(blank=True, null=True, auto_now_add=True)
    updated_at = models.DateTimeField(blank=True, null=True, auto_now=True)
    deleted_at = models.DateTimeField(blank=True, null=True)
    image_prompt = models.ForeignKey(ImagePrompts, models.DO_NOTHING,
                                     blank=True, null=True)
    image_prompt_subcategory = models.ForeignKey(ImagePromptSubcategories,
                                                 models.DO_NOTHING, blank=True,
                                                 null=True)

    class Meta:
        managed = False
        db_table = 'image_prompts_subcategories'

and I want to use Django-smart-selects to only show in the select the subcategories that are related to the category shown in “ImagePrompts”

Show where? Are you talking about in the admin here, or in one of your views? What model are you creating this form from?

I want show in my view with form based in ImagePrompts model

I try this, but dont work

class ImagePrompts(models.Model):
    id = models.BigAutoField(primary_key=True)
    created_at = models.DateTimeField(blank=True, null=True, auto_now_add=True)
    updated_at = models.DateTimeField(blank=True, null=True, auto_now=True)
    deleted_at = models.DateTimeField(blank=True, null=True)
    image_prompt_category = models.ForeignKey(ImagePromptCategories,
                                              models.DO_NOTHING, blank=True,
                                              null=True)
    image_prompt_subcategories = models.ManyToManyField(
        ImagePromptSubcategories,
        through='ImagePromptsSubcategories',
        blank=True
    )
    prompt = models.TextField(blank=True, null=True)
    example_url = models.TextField(blank=True, null=True)
    example_url_thumb = models.TextField(blank=True, null=True)
    prompt_position = models.TextField()
    style_preset = models.TextField(blank=True, null=True)
    icon = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'image_prompts'


class ImagePromptsSubcategories(models.Model):
    id = models.BigAutoField(primary_key=True)
    created_at = models.DateTimeField(blank=True, null=True, auto_now_add=True)
    updated_at = models.DateTimeField(blank=True, null=True, auto_now=True)
    deleted_at = models.DateTimeField(blank=True, null=True)
    image_prompt = models.ForeignKey(ImagePrompts, models.DO_NOTHING,
                                     blank=True, null=True)
    # image_prompt_subcategory = models.ForeignKey(ImagePromptSubcategories,
    #                                              models.DO_NOTHING, blank=True,
    #                                              null=True)
    image_prompt_subcategory = ChainedForeignKey(
        ImagePromptSubcategories,
        chained_field='image_prompt_category',
        chained_model_field='image_prompt_category',
        show_all=False,
        auto_choose=True,
        sort=True
    )

    class Meta:
        managed = False
        db_table = 'image_prompts_subcategories'

First, a side note: I hope you have noticed that django-smart-selects is a not-well-maintained package. The last PyPi version is 16 months old and only tested through Django 4.0, and the github main branch had its last commit about 6 months ago. This is not a package that I would be looking to adopt.

To try and rephrase for my understanding.

You’re creating a ModelForm for ImagePrompts.

In that form, you have two fields, image_prompt_category and image_prompt_subcategories.

The image_prompt_category is a ModelChoiceField.

The image_prompt_subcategories is a ModelMultipleChoiceField.

You want the options being displayed in the image_prompt_subcategories to be limited to those ImagePromptSubcategories that are related to the same ImagePromptCategories as the image_prompt_category field.

Assuming this is correct, the ChainedManyToManyField definition would belong in the ImagePrompts model.

Side note: I don’t understand what the purpose is of that ImagePromptsSubcategories model. It seems to me that you have an unnecessary (near) duplication of models here creating the confusion. I only see a need for the ImagePromptSubcategories. You may want to take another look at how your data models are structured.

exactly, your understanding is right about the models, i use inspectdb for create models because is the legacy db.

My question is how i can use ChainedManyToManyField in ImagePrompts with “through” model ImagePromptsSubcategories

Visual:

I would suspect that you use it the same way you would use it with any ManyToManyField. Define it as a ChainedManyToManyField with the addition of the through parameter.

1 Like

thanks! now is working.