Thanks Julien for the quick answer
Indeed i have a question : Is it possible to make a sort on a @property field in django (let me explain above)
Here is my implementation :
I have a model in the core
app
class CompanyWebsite(models.Model):
website = models.CharField(max_length=250, null=True)
http_status = models.IntegerField(default=500, null=True)
domain = models.CharField(max_length=250, null=True)
meta_description = models.CharField(max_length=500, null=True)
content = models.CharField(max_length=5000, null=True)
company = models.ForeignKey(
Company,
related_name='possible_websites',
on_delete=models.CASCADE,
null=True
)
@property
def score(self):
return self.health_score + self.website_score + self.content_score
@property
def health_score(self) -> Literal[100, 70, 0]:
if self.http_status < 300:
return 100
elif self.http_status < 500:
return 70
else:
return 0
@property
def content_score(self) -> Literal[-100, 50, 0]:
if not self.content:
return 0
...
return 50
The view
from django_forest.resources.views.list import ListView
class CompanyWebsiteView(ListView):
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, "core_companywebsite", *args, **kwargs)
def get(self, request, *args, **kwargs):
# the redefinition of the search param
request.GET._mutable = True # by default we can't modify the GET request
# to sort fullname by firstname
# request.GET['sort'] = request.GET['sort'].replace("Score", "firstname")
request.GET._mutable = False
return super().get(request)
The fields
from django_forest.utils.collection import Collection
from core.models import CompanyWebsite
class CompanyWebsiteForest(Collection):
def load(self):
self.fields = [
{
'field': 'Score',
'type': 'Number',
'is_sortable': True,
'get': self.get_score
},
{
'field': 'Health score',
'type': 'Number',
'is_sortable': True,
'get': self.get_health_score
},
{
'field': 'Website score',
'type': 'Number',
'is_sortable': True,
'get': self.get_website_score
},
{
'field': 'Content score',
'type': 'Number',
'is_sortable': True,
'get': self.get_content_score
},
]
def get_score(self, company_website):
return company_website.score
def get_health_score(self, company_website):
return company_website.health_score
def get_website_score(self, company_website):
return company_website.website_score
def get_content_score(self, company_website):
return company_website.content_score
Collection.register(CompanyWebsiteForest, CompanyWebsite)
The urls file :
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from core.views.company import ConsolidateCompany, QualifyCompanies, FindCTO
from core.views.company_website import CompanyWebsiteView
app_name = 'core'
urlpatterns = [
path('/core_companywebsite', csrf_exempt(CompanyWebsiteView.as_view()), name='core_companywebsite')
]
The error i got :
Internal Server Error: /forest/core_company/2276/relationships/possible_websites
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 56, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 55, in wrapped_view
return view_func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 103, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django_forest/resources/utils/resource.py", line 13, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 142, in dispatch
return handler(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django_forest/resources/associations/views/list.py", line 27, in get
queryset = self.enhance_queryset(queryset, RelatedModel, params, request)
File "/usr/local/lib/python3.9/site-packages/django_forest/resources/utils/queryset/__init__.py", line 34, in enhance_queryset
queryset = queryset.order_by(params['sort'].replace('.', '__'))
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 1645, in order_by
obj.query.add_ordering(*field_names)
File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 2202, in add_ordering
self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)
File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/query.py", line 1709, in names_to_path
raise FieldError(
django.core.exceptions.FieldError: Cannot resolve keyword 'Score' into field. Choices are: company, company_id, content, domain, http_status, id, meta_description, website
In the error i dont see my @property fields and i want to filter on it
What should i do, to make it work ?