# Exclude-By Primary Author ## Example Overview This example shows how to dynamically exclude options in one field based on the selection in another, using the `exclude_by` parameter. The "Contributing Authors" field excludes whoever is chosen as "Primary Author" so the same person can't fill both roles, and stays empty until a Primary Author is selected. Reach for this pattern whenever overlapping selections between two related fields would be invalid or redundant. **Visual Examples** ![Screenshot: Exclude-By Primary Author](https://raw.githubusercontent.com/OmenApps/django-tomselect/refs/heads/main/docs/images/exclude-by-primary-author.png) ## Key Code Segments ### Forms The form uses `TomSelectModelChoiceField` for the "Primary Author" and `TomSelectModelMultipleChoiceField` for "Contributing Authors". The `exclude_by` parameter ensures contributing authors exclude the selected primary author. :::{admonition} Form Definition :class: dropdown ```python class ExcludeByPrimaryAuthorForm(forms.Form): """Form with dependent fields demonstrating exclude_by functionality.""" primary_author = TomSelectModelChoiceField( config=TomSelectConfig( url="autocomplete-author", value_field="id", label_field="name", css_framework="bootstrap5", ), ) contributing_authors = TomSelectModelMultipleChoiceField( config=TomSelectConfig( url="autocomplete-author", value_field="id", label_field="name", exclude_by=("primary_author", "id"), css_framework="bootstrap5", placeholder=_("Select contributing authors..."), highlight=True, max_items=None, plugin_remove_button=PluginRemoveButton(), ), attrs={"class": "form-control mb-3"}, required=False, ) ``` ::: **Explanation**: - The `exclude_by` parameter in the `contributing_authors` field ensures that any selected "Primary Author" is removed from the available options in the "Contributing Authors" field. - The `RemoveButton` plugin improves user interaction by enabling quick removal of selected contributing authors. ### Templates The form is rendered in the `exclude_by.html` template, highlighting the exclusion mechanism between the two fields. :::{admonition} Template Code :class: dropdown ```html {% extends 'example/base_with_bootstrap5.html' %} {% block extra_header %} {{ form.media }} {% endblock %} {% block content %}

Exclude-By Primary Author Demo

This page demonstrates how to exclude available options based on the selected value of another field. In this case, the options for Contributing Author include all except the selected Primary Author.
{% csrf_token %} {{ form.as_div }}
{% endblock %} ``` ::: **Key Elements**: - Bootstrap 5 for clean and modern styling. - The exclusion logic is visually reflected in the dropdowns as selections are made. ### Autocomplete Views The `autocomplete-author` endpoint serves data for both fields, ensuring proper exclusion logic based on the `exclude_by` parameter. - We override the `get_queryset` method to filter authors based on the selected magazine (if any). - The `hook_prepare_results` method adds a formatted name to each author result for better readability. :::{admonition} Autocomplete View :class: dropdown ```python class AuthorAutocompleteView(AutocompleteModelView): """Autocomplete view for Author model with annotations and advanced searching.""" model = Author search_lookups = [ "name__icontains", "bio__icontains", ] ordering = ["name"] page_size = 20 value_fields = ["id", "name", "bio", "article_count", "active_articles"] list_url = "author-list" create_url = "author-create" update_url = "author-update" delete_url = "author-delete" skip_authorization = True def get_queryset(self): """Return a queryset of authors with article count annotations. Annotates: - Total number of articles by author - Number of active articles by author - Articles by magazine (as a string list) """ queryset = super().get_queryset().with_details() # Filter by magazine if specified magazine_id = self.request.GET.get("magazine") if magazine_id: queryset = queryset.filter(article__magazine_id=magazine_id) return queryset def hook_prepare_results(self, results: list[dict[str, Any]]) -> list[dict[str, Any]]: """Add formatted_name to each result.""" for author in results: author["formatted_name"] = f"{author['name']} ({author['article_count']} articles)" return results ``` ::: See the Article List and Create example for a more comprehensive demonstration, which includes this functionality.