Is it possible to do a reverse relation search on the Django Admin interface?
My Django app database schema consists of the following models:
class Tag(models.Model):
title = models.CharField(max_length=50)
class Publication(models.Model):
title = models.CharField(max_length=200)
tags = models.ManyToManyField(Tag, blank=True, related_name="publications")
I have added a search field for looking up tags by title in my admin.py file by doing:
class TagAdmin(admin.ModelAdmin):
list_display = ('title',)
search_fields = ('title',)
Thus, when I type a tag title into the search field on the django admin interface, a list of matching tag titles comes up. Now I'd like to make it so that if I type a tag title into the search field, matching publications come up.
In other words, I'm imagining something like:
class TagAdmin(admin.ModelAdmin):
list_display = ('title',)
search_fields = ('publications',)
Which of course doesn't work... but that's the idea...
Is this even possible? And/or am I even going about this the right way? If so, could someone suggest a way to do this or a resource? If you are kind enough to do so, please keep in mind that I am very much a beginner. Thanks.
You shouldn't try to do this using an admin class registered to your Tag model. Instead, set up an admin class for Publication and set its search_fields:
class PublicationAdmin(admin.ModelAdmin):
list_display = ('title',)
search_fields = ('tags__title',)
Related
I'm new to programming.
In my blog I want to show a list of categories.
If I create a queryset like this:
Category.objects.all()
my django-modeltranslation works perfectly.
But I want to get categories of only published posts. Then my queryset is:
Post.objects.values('category__name').filter(is_published=True)
However, django-modeltranslation doesn't work. I get values from 'name' field instead 'name_en' or 'name_ru' fields.
What is wrong?
Here's my models.py :
class Category(models.Model):
name = models.TextField(max_length=100)
url = models.SlugField(max_length=160, unique=True)
class Post(models.Model):
title = models.TextField('title', max_length=150)
category = models.ManyToManyField(Category, related_name='posts', blank=True)
I think you better query in reverse: with .values(…) you select a specific database column, so this will omit the model logic.
You can retrieve the categories with:
Category.objects.filter(posts__is_published=True).distinct()
I am displaying data in Django admin panel for many to many relationship tables. I got None instead of a list of names.
I am using:
Python: 3.6
Django: 2.2
List_display for ManytoMany fields in Admin panel
I had also already asked a related question on this topic. That being said I changed my model since then (I also got not answers).
models:
class Assessment(models.Model):
name = models.CharField(max_length=255)
class Participant(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
first_name = models.CharField(max_length=255,blank=True,null=True)
class Seminar(models.Model):
topic = models.CharField(max_length=255)
assessment = models.ManyToManyField(Assessment,blank=True)
participant = models.ManyToManyField(Participant,blank=True,through='SeminarParticipant',through_fields=('seminar','participant'))
class SeminarParticipant(models.Model):
seminar = models.ForeignKey(Seminar,blank=True,on_delete=models.CASCADE)
participant = models.ForeignKey(Participant,blank=True,on_delete=models.CASCADE)
request_time = models.PositiveIntegerField(default=0,validators=[MinValueValidator(0),])
is_survey_completed = models.BooleanField(default=False)
admin:
#admin.register(Seminar)
class SeminarAdmin(admin.ModelAdmin):
list_display = ('topic''assessment')
def assessment(self,obj):
return "\n".join([item for item in obj.assessment.all()])
I was expecting name of assessment in list_display of seminar admin but got assessments.Assessment.None in list_display of admin panel.
Snapshot of output:
Thank you very much for your help
assessment is the name of the field, which will be found before your method. Call the method something else and use that name in list_display.
class SeminarAdmin(admin.ModelAdmin):
list_display = ('topic', 'assessment_list')
def assessment_list(self, obj):
return "\n".join([item for item in obj.assessment.all()])
(Although note, assessment is an odd name for a field that contains many assessments; you should think about renaming the field itself.)
I am new with python and django, i want to know how can i implement the admin search bar on my project model? i notice that the user model has it by default.
My code is below, after the makemigration command still no search bar i think i am missing something. sorry for the noob question.
class Todo(models.Model):
search_fields = ('title', 'text', 'created_at',)
title = models.CharField(max_length=200)
text = models.TextField()
created_at = models.DateTimeField(default=datetime.now)
def __str__(self):
return self.title
in the apps admin.py
inside the class for which you are registering the model
add
search_fields = ['column_name']
add search fields in admin file instead of models file
Is there a way to de-couple django admin inline-models from clustering like models together?
A bit of context: I have a model named Page with two inline-models, TextBlock and GalleryContainer. I would to render TextBlocks and GalleryContainers on a template based on the order they're added in the Page admin editor. The default django-admin display looks like this:
I would like it to display as:
Gallery Container 1
Textblock 1
Gallery Container 2
But I have no idea how to do that. Any suggestions or nudges in the right direction would be a great help. Thanks in advance. (I also hope my question makes sense...)
If you want a relation between a column and a gallery your models should reflect that. So if I understand correctly: A page has name and columns. A column has text, gallery (optional) and ordering.
models.py:
class Page(models.Model):
name = models.CharField(max_length=200)
class Gallery(models.Model):
name = models.CharField(max_length=200)
class Column(models.Model):
page = models.ForeignKey(Page)
text = models.TextField()
gallery = models.ForeignKey(Gallery, null=True, blank=True) # Optional
ordering = models.IntegerField()
class Meta:
ordering = ('ordering', )
This example shows how ordering is done by an IntegerField. If you want to order the columns based on the moment they where added replace
ordering = models.IntegerField()
with
models.datetimeField(auto_now_add=True)
In your admin.py:
class ColumnInline(admin.TabularInline): # or StackedInline
model = Column
class PageAdmin(admin.ModelAdmin):
inlines = [
ColumnInline,
]
Note: I put your 'gallery display name' in Gallery as 'name'. Makes more sense to give the gallery it's name only once. But if a gallery is in more places with different names, than you need a field (e.g. 'gallery_display_name=models.CharField(max_lenght=200)') on the Column model.
Is this the answer to your question? I hope it helps!
I've got a weird problem in django admin list_display. Whenever I add a foreign key to a list_display the whole change list view goes blank showing only the total no of entries.
models.py:
class Organization(models.Model):
org_id = models.AutoField(primary_key=True)
org_name = models.CharField(max_length=288)
def __unicode__(self):
return self.org_name
class Meta:
db_table = u'organization'
class Server(models.Model):
server_id = models.AutoField(primary_key=True)
server_name = models.CharField(max_length=135,verbose_name="Server Name")
org = models.ForeignKey(Organization,verbose_name="Organization")
def __unicode__(self):
return self.server_name
class Meta:
db_table = u'server'
admin.py:
class ServerAdmin(admin.ModelAdmin):
list_display = ('server_name','org')
admin.site.register(Server,ServerAdmin)
Now I'd expect this code to show me the organization name in the ChangeList View, But instead I get this:
If I remove the org in the list_display of ServerAdmin class, I get this:
I didn't modify the template or override any ModelAdmin methods. I'm using Mysql(5.1.58) as my database that comes with ubuntu 11.10 repository.
I'll be really glad if I could a get a sloution for this problem guys. Thanks in advance.
I second Stefano on the fact that null=True, blank=True is to be added. But, I think you only need to add it to the org_name field of the Organization model. That should make your way through. It has to be done because you have run inspectdb to create models from your legacy DB. And probably the organization table in the DB has an empty string stored. So, adding the above would allow the Admin to have a blank field/column displayed.
Moreover, you can also try using callbacks in situations where you don't want to make changes to your model definition like the above.
Try adding null=True, blank=True to all your model fields.
Usually django admin will silenty fail (thus show no records in the list) if the row does not validate the model constraints.
See: https://stackoverflow.com/a/163968/1104941
Does the following work for you?
admin.py:
class ServerAdmin(admin.ModelAdmin):
list_display = ('server_name','org__org_name')
admin.site.register(Server,ServerAdmin)
I had a similar problem and solved it like this (using your example):
class ServerAdmin(admin.ModelAdmin):
list_display = ('server_name', 'get_org')
def get_org(self, obj):
return obj.org.org_name
get_org.short_description = 'Org'
admin.site.register(Server,ServerAdmin)