coderedcorp / coderedcorp/coderedcms

ClassifierSelectWidget should respect `limit_choices_to` on model field

Aperta
#713 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
Type: Bug
Lingua principale
Python
Stelle
765
Fork
154
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

#### Describe the bug
ClassifierSelectWidget always shows all classifiers and terms even if the underlying model field definition restricts choices using `limit_choices_to`. This allows users to click on invalid options causing the form to fail validation.

#### Steps to reproduce
Steps to reproduce the behavior:
1. Set up a classifier with multiple terms. For this example I'm imagining a classifier called "Genre" with the terms "Action", "Adventure", "Horror", "Thriller", "Science-Fiction".
2. Make a snippet model (new or existing) with the following field:
```python
classifier_terms = ParentalManyToManyField(
'coderedcms.ClassifierTerm',
blank=True,
related_name="genres",
limit_choices_to=Q(name__startswith="A"), # or any filter eliminates some terms.
)
```
3. In the model's `panels` attribute, include `FieldPanel("classifier_terms", widget=ClassifierSelectWidget())`.
4. Run migrations, register snippet, etc.
5. Go to the snippet edit page for the snippet.
6. Scroll to the "classifier terms" panel. See that all of the terms are present, not just ones matching the `Q` object.
7. Select both a matching term and a non-matching term, and save the form. The form validation should fail and the error message should complain only about the ID of the non-matching term.

#### Expected behavior
Only the terms and classifiers matching the `limit_choices_to` filter should be available as choices, as happens when not using the ClassifierSelectWidget(). `CheckboxSelectMultiple` is very close to what I want, but it is not grouped by classifier.

#### Additional context
This should theoretically be a simple matter of updating the `optgroups` class to use `self.choices.queryset`.

I made a simple working example by changing the initial classifier queryset from `Classifier.objects.all().select_related()` to

```python

classifiers = Classifier.objects.all().select_related().prefetch_related(
Prefetch("terms", queryset=self.choices.queryset)
)
```
to stop Classifiers with no matching terms from appearing as empty groupings, I just changed the inner loop to this:

```python

if terms := classifier.terms.all():
for term in terms:
```

If this seems like something y'all would be interested in implementing, I could try my hand at making a merge request. Wanted to confirm that the team would consider it worthwhile.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Direzione di ricerca

Inizia da ClassifierSelectWidget.optgroups e analizza in che modo l’iterazione di classifier e term utilizza self.choices.queryset. Riproduci l’esempio fornito di ParentalManyToManyField, quindi verifica che vengano mostrati solo i termini corrispondenti e i gruppi classifier non vuoti e che le selezioni non valide non passino più alla validazione del form.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
django, python
Ambito
backend
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
45/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.