Repository: netbox-community/netbox

Issue:
Individual ASN view broken when sorting by circuit count
### NetBox version

v3.2.2

### Python version

3.8

### Steps to Reproduce

1. Connect to Netbox and authenticated yourself.
2. Navigate to any kind of view that displays a link to an ASN object, and click on that link


### Expected Behavior

Display of the detail page of the selected ASN object.

### Observed Behavior

A field error exception was raised:

---
<class 'django.core.exceptions.FieldError'>

Cannot resolve keyword 'count_circuits' into field. Choices are: account, admin_contact, asn, asns, circuits, comments, contacts, created, custom_field_data, id, journal_entries, last_updated, name, networks, noc_contact, portal_url, slug, tagged_items, tags

Python version: 3.8.10
NetBox version: 3.2.2

---

Please note that in our context unauthenticated users have a read only rights to most object types and that, strangely, **only authenticated users trigger this behaviour.**


Discussion:
Worse than that. Dug deeper. Found that I seem to be the only impacted user. I also happen to be the only user to have worked on ASNs and providers since the upgrade from 3.1.7 to 3.2.2.
> Navigate to any kind of view that displays a link to an ASN object, and click on that link

Please say _exactly_ what you're doing.
I managed to replicate this, I think it's a side effect caused by https://github.com/netbox-community/netbox/commit/0301aec409fbf29834d3a4cfbecb481a60ec6b8a

I'm not at a computer with access to my own netbox instance, so these steps are when importing netbox-demo-data:

* Import https://github.com/netbox-community/netbox-demo-data
* Go to Circuits -> Providers
* Sort table by the "Circuits" column
* Go to IPAM -> ASNs
* Click any ASN

Workaround is to clear table preferences for ProviderTable.
> Please say _exactly_ what you're doing.

I could have said "Go to IPAM/ASN and click any ASN" but I checked that it also occured when clicking on an ASN link from anywhere some of these appear. I was  in a rush and tried to convey that information. Obviously it was not the right way to put it.  Next time I'll add it in a comment below instead, to avoid confusion.

About the "sorting provider by circuits count", I did do that, yes. But I had spent so much time working on providers and ASN yesterday and this morning that there was absolutely no way I could have remembered and made the link between this action and the bug. I did see that the issue came from a nested request for provider data when displaying the ASN, but that was about it. My understanding did not go beyond that and I can't try and debug anything in my current work env. I could only have investigated more from home. So... Sorry for the bad quality of the bug report but it was the best I could do at that time.

I do have a doubt about the culprit designated by @kkthxbye-code. Isn't this code change supposed to be present in v3.2.3 and not 3.2.2? I have the issue in 3.2.2, unless my colleagues went for an unannounced  upgrade when I was having lunch. And I am 99% certain that I checked the current version when I started having problems.

Edit: typo
> I do have a doubt about the culprit designated by @kkthxbye-code. Isn't this code change supposed to be present in v3.2.3 and not 3.2.2? I have the issue in 3.2.2, unless my colleagues went for an unannounced upgrade when I was having lunch. And I am 99% certain that I checked the current version when I started having problems.

My bad, I missed that you were on 3.2.2. It's probably just a missing annotation for the queryset then.

Resolving patch:
diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py
--- a/netbox/ipam/views.py
+++ b/netbox/ipam/views.py
@@ -4,7 +4,7 @@
 from django.shortcuts import get_object_or_404, redirect, render
 from django.urls import reverse
 
-from circuits.models import Provider
+from circuits.models import Provider, Circuit
 from circuits.tables import ProviderTable
 from dcim.filtersets import InterfaceFilterSet
 from dcim.models import Interface, Site
@@ -225,7 +225,9 @@ def get_extra_context(self, request, instance):
         sites_table.configure(request)
 
         # Gather assigned Providers
-        providers = instance.providers.restrict(request.user, 'view')
+        providers = instance.providers.restrict(request.user, 'view').annotate(
+            count_circuits=count_related(Circuit, 'provider')
+        )
         providers_table = ProviderTable(providers, user=request.user)
         providers_table.configure(request)
 


Test patch: