I am building a django project and try to get a search bar on a "main" field which is called "regnr" (see models & admin modules below) but I get ani contains error when I search. I have tried search_fields = [foreignkey__name] and also [name_id] and also. [name] but nothing seems to work...
from django.db import models
# Create your models here.
class Fordonsregister(models.Model):
regnr = models.CharField(max_length=6, primary_key=True, null=False, blank=False)
namn = models.CharField(max_length=255, null=True, blank=True)
tel = models.CharField(max_length=255, default='070-000 00 00', null=True, blank=True)
email = models.EmailField(null=True, blank=True)
kund_sedan = models.DateTimeField(auto_now=True)
kund_points = models.IntegerField(default=0)
def __str__(self) -> str:
return self.regnr
class Meta:
ordering = ['regnr']
class ServiceTypes(models.Model):
typ = models.CharField(max_length=255, primary_key=True, blank=False)
pris = models.DecimalField(decimal_places=2, max_digits=6, null=False, blank=False)
beskrivning = models.CharField(max_length=255, null=True, blank=True)
def __str__(self) -> str:
return self.typ
class Meta:
ordering = ['typ']
class FordonsService(models.Model):
regnr = models.ForeignKey(Fordonsregister, on_delete=models.CASCADE)
typ = models.ForeignKey(ServiceTypes, on_delete=models.CASCADE)
service_datum = models.DateTimeField()
bokat_datum = models.DateTimeField(auto_now=True)
kommentar = models.CharField(max_length=1000)
class Meta:
ordering = ['-service_datum']
And here is the admin module: The problem is with class FordonsServiceAdmin(admin.ModelAdmin):
from django.contrib import admin
from django.db.models import Count
from django.utils.html import format_html, urlencode
from django.urls import reverse
from django.http import HttpRequest
from .models import Fordonsregister, ServiceTypes, FordonsService
# Register your models here.
@admin.register(Fordonsregister)
class FordonsregisterAdmin(admin.ModelAdmin):
list_display = ['regnr', 'namn', 'tel', 'email', 'antal_bokningar', 'antal_offerter']
search_fields = ['regnr__istartswith']
def antal_bokningar(self, fordonsregister):
url = (
reverse('admin:main_fordonsservice_changelist')
+ '?'
+ urlencode({
'fordonregister__regnr': str(fordonsregister.regnr)
}))
return format_html('<a href="{}">{}</a>', url, fordonsregister.antal_bokningar)
def antal_offerter(self, fordonsregister):
url = (
reverse('admin:kalkylator_standardoffert_changelist')
+ '?'
+ urlencode({
'fordonsregister__regnr': str(fordonsregister.regnr)
}))
return format_html('<a href="{}">{}</a>', url, fordonsregister.antal_offerter)
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(antal_bokningar=Count("fordonsservice__service_datum"),
antal_offerter=Count("standardoffert__totalpris"))
return queryset
@admin.register(FordonsService)
class FordonsServiceAdmin(admin.ModelAdmin):
list_display = ['regnr', 'typ', 'service_datum', 'bokat_datum', 'regnr_id']
search_fields = ['fordonsregister__regnr_id']
@admin.register(ServiceTypes)
class ServiceTypesAdmin(admin.ModelAdmin):
list_display = ['typ', 'pris', 'antal_bokat']
def antal_bokat(self, servicetypes):
url = (
reverse('admin:main_fordonsservice_changelist')
+ '?'
+ urlencode({
'servicetypes__typ': str(servicetypes.typ)
}))
return format_html('<a href="{}">{}</a>', url, servicetypes.antal_bokat)
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(antal_bokat=Count("fordonsservice__service_datum"))
return queryset
Your FordonsService
model has a foreign key regnr
that points to the Fordonsregister
model, which in turn has another CharField
named regnr
(maybe you can be a bit descriptive while naming attributes -- it will be helpful for you as well as others that will be working on the code).
Now, since you want to go from the foreign-key regnr
and access any field on the Fordonsregister
model, you do it via model__attribute
syntax, like below:
@admin.register(FordonsService)
class FordonsServiceAdmin(admin.ModelAdmin):
list_display = ['regnr', 'typ', 'service_datum', 'bokat_datum', 'regnr_id']
search_fields = ['regnr__id', 'regnr__regnr']
This will add a search for both the id
and the regnr
attributes of the Fordonsregister
model, which is linked to the FordonsService
model.