I'd like to combine the same table data from the inventory admin page list.
My admin.py is as follows
admin.py
class CounselAdmin(admin.ModelAdmin):
list_display = ('counsel_idx', 'show_firm_url', 'answer_count', 'counsel_status', 'deleted', 'register_date',)
search_fields = ('counsel_status',)
list_filter = ('counsel_status',)
def show_firm_url(self, obj):
return format_html("<a href='/admin/counsel/view/{0}'>{1}</a>", obj.counsel_idx, obj.counsel_title)
show_firm_url.short_description = 'title'
For example, I would like to put it together in this way
show_firm_url
The data in show_firm_url is = TITLE TEST
answer_count is = 7
in case of
TITLE TEST (answercount 7)
I want it to come out together like a stomach.
Please help me.
You can try like this:
class CounselAdmin(admin.ModelAdmin):
list_display = ('show_firm_url', 'counsel_idx', 'show_firm_url', 'answer_count', 'counsel_status', 'deleted', 'register_date',)
search_fields = ('counsel_status',)
list_filter = ('counsel_status',)
def show_firm_url(self, obj):
return format_html("<a href='/admin/counsel/view/{0}'>{1}(answercount {2})</a>", obj.counsel_idx, obj.counsel_title, obj.answer_count)
show_firm_url.short_description = 'title'
Related
I am using django-filter to filter my Queryset on the basis of url params.
class WorklistViewSet(ModelViewSet):
serializer_class = MySerializer
queryset = MyModel.objects.all()
filter_backends = [DjangoFilterBackend, ]
filterset_fields = ['class', ]
# possible values of *class* which is allowed to be passed in the url params are ['first', 'second', 'ALL'].
class MyModel(BaseModel):
CLASS_CHOICES = (
(FIRST_CLASS, 'first'),
(SECOND_CLASS, 'second'),
)
class = models.CharField(choices=CLASS_CHOICES, max_length=3, )
URLs http://127.0.0.1:8000?class=first and http://127.0.0.1:8000?class=first are giving the expected results.
I want that when http://127.0.0.1:8000?class=ALL is called, all the records in my table should be listed i.e without filtering.
How can i do this while using django-filter ?
You may want to use Filter.method, as explained in the docs.
In your case, I would do as follows:
class F(django_filters.FilterSet):
klass = CharFilter(method='my_custom_filter')
class Meta:
model = MyModel
fields = ['klass']
def my_custom_filter(self, queryset, name, value):
if value == 'ALL':
return queryset
return queryset.filter(**{
name: value,
})
Be also reminded that class is a reserved word in Python and cannot be used as a variable name. I've used klass instead, although that's used as something else in many Python books and may be confusing.
I have this code in my admin-site,
#admin.register(StudentsEnrollmentRecord)
class StudentsEnrollmentRecord(admin.ModelAdmin):
list_display = ('Student_Users', 'School_Year', 'link',)
ordering = ('Education_Levels',)
list_filter = ('Student_Users',)
Django-adminsite
i just want to add an html_link here and filter what studentenrollmentrecord selected
You can create a function to be used as field:
#admin.register(StudentsEnrollmentRecord)
class StudentsEnrollmentRecord(admin.ModelAdmin):
list_display = ('Student_Users', 'School_Year', 'link_display',)
ordering = ('Education_Levels',)
list_filter = ('Student_Users',)
def link_display(self, obj):
your_url = '' # Define your URL here
return 'link'.format(your_url)
link_display.allow_tags = True
link_display.short_description = 'link'
The function receive the current object as first parameter (obj).
You need to set the allow_tags property to render your link.
You can optionally customize the description (displayed in the header) with short_description.
I want to make a complex filtering on the page using the FilterSets. This is my Filterset, nicely showing me tuples from chosen time and with chosen parameters.
# filters.py
class workFilter(filters.FilterSet):
start__gt = filters.DateTimeFilter(name='time_start', lookup_expr='gte')
start__lt = filters.DateTimeFilter(name='time_end', lookup_expr='lte')
class Meta:
model = Work
fields = ('machine', 'program')
But I want to add charts explaining the queried data. For that I need informations, like overall count of time. I am querying them like that:
#views.py
def search(request):
work_list = Work.objects.all()
work_filter = workFilter(request.GET, queryset=work_list)
filter_backends = (filters.DjangoFilterBackend,)
#some queries to add to context, such as
sum_work = Work.objects.aggregate(Sum('time'))['time__sum']
return render_to_response(
TEMPLATE_DIRS + 'index.html',
{
'filter': praca_filter,
'sum_work': sum_work,
}
)
But sadly, those queries are according to whole database, not to my filtered set of object.
How can I make queries on filtered set work_filter?
Define sum_work as a property of your FilterSet.
class WorkFilter(filters.FilterSet):
start__gt = filters.DateTimeFilter(name='time_start', lookup_expr='gte')
start__lt = filters.DateTimeFilter(name='time_end', lookup_expr='lte')
class Meta:
model = Work
fields = ('machine', 'program')
#property
def work_sum(self):
qs = super(WorkFilter, self).qs
return qs.aggregate(Sum('time'))['time__sum']
Then when you pass your filter through to your view you just need {{ filter.work_sum }} in your template.
I can't figure out how to make admin able to sort records using custom column - hours_to_deadline (when they clicks on the column header). In my case, it's timedelta.
class JobAdmin(SuperModelAdmin):
...
list_display = ['id', 'identificator', 'created', 'invoice__estimated_delivery','hours_to_deadline','customer__username', 'language_from__name', 'language_to__name',
'delivery__status', 'confirmed', 'approved', 'invoice__final_price']
...
def hours_to_deadline(self,obj):
try:
return (obj.invoice.estimated_delivery - now())
except:
return None
I found this solution: https://stackoverflow.com/a/15935591/3371056
But in my case, I can't just do sum or something similar.
Do you know what to do?
You cannot order by a field that is not an actual database field, because all the sorting is done on the database level. If it has a value related somehow to a database field you can do something like that in the model definition:
hours_to_deadline.admin_order_field = 'database_field'
You can read more about it at
https://docs.djangoproject.com/en/1.10/ref/contrib/admin/
Answer is: ordering = ('-id',)
class JobAdmin(SuperModelAdmin):
list_display = ['id', 'identificator', 'created', 'invoice__estimated_delivery','hours_to_deadline','customer__username', 'language_from__name', 'language_to__name',
'delivery__status', 'confirmed', 'approved', 'invoice__final_price']
ordering = ('-id',)
def hours_to_deadline(self,obj):
try:
return (obj.invoice.estimated_delivery - now())
except:
return None
Let's say I have the following design
database table
A track has a song and a song has a singer.
I would like the track allows filtering based on singer name too.
So, I need the track model extract the singer name. I got stuck with the filters.
I receive the following error message:
File ".../lib/python3.6/site-packages/django_filters/filterset.py", line 352, in get_filters
"%s" % ', '.join(undefined)
TypeError: 'Meta.fields' contains fields that are not defined on this FilterSet: singer
I have heard from this to use __ but I have no idea how to apply that.
Here is the code
class TrackSerializer(MyModelSerializer):
singer = serializers.SerializerMethodField()
def get_singer(self, track): # Is there any shortcut?
song = Song.objects.get(id=track.song_id)
if song is not None:
return Channel.objects.get(id=song.singer_id).name
else:
return ''
class Meta:
model = Track
fields = (
'id',
'name',
'song',
'singer',
)
class TrackFilterSet(MyFilterSet):
singer = CharFilter(method='singer_filter')
song = RefineModelChoiceFilter(
queryset=Song.objects.all(),
refine_choices=lambda qs, keywords, request: qs.filter(name__icontains=keywords)
)
def singer_filter(self, queryset, name, value):
# print('queryset:', TrackSerializer(queryset, many=True))
return queryset.filter(**{
name: value, # ???????????
})
class Meta:
model = Track
fields = (
'singer',
'song',
)
class TrackViewSet(MyViewSet):
queryset = Track.objects.all()
serializer_class = TrackSerializer
filterset_fields = ('singer', 'song')
def filter_refine_choices_singer(self, qs, keywords, request):
return qs.filter(name__icontains=keywords)
def filter_refine_choices_song(self, qs, keywords, request):
return qs.filter(name__icontains=keywords)
try putting filterset_fields as an array, between [] rather that ().
filterset_fields = ['singer', 'song']
I think i the method singer_filter you should so something like :
def singer_filter(self, queryset, name, value):
return queryset.filter(song_id__singer_id__name_icontains=value)
I didn't test this but i think something like that should work unless third relation __ is not allowed. Take a look here:
https://django-filter.readthedocs.io/en/master/ref/filters.html?highlight=method