I have a model with property and I want to be able to sort instances in the admin panel by that property.
My model with _points property:
class CustomUser(models.Model):
inviter = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True)
#property
def _points(self):
res = CustomUser.objects.filter(inviter_id=self.id).count()
return res
My admin:
class CustomUserAdmin(admin.ModelAdmin):
list_display = ['inviter', '_points']
class Meta:
model = CustomUser
the _points field is displayed in the admin panel, but I cannot sort entries by it
It is not possible to order a queryset by a property. You can only order it by database fields
Related
I have these two models:
class User(AbstractUser):
is_teacher = models.BooleanField(default=False, null=False)
class Course(models.Model):
teacher = models.ForeignKey(User, on_delete=models.CASCADE, related_name='teacher_courses')
students = models.ManyToManyField(User, blank=True, related_name='student_courses')
Course model has a ManyToMany field and a ForeignKey to User model. In django's admin page, you are able to see a course's student/teacher. Is there a way to make it as you can have a list of a user's courses in admin page to see/add/remove courses for a user?
You can define a callable on your ModelAdmin class and add it to list_display. To make the courses editable on an user's page use sub classes of InlineModelAdmin.
class TeacherCourseInlineAdmin(admin.TabularInline):
model = Course
fk_name = "teacher"
class StudentCourseInlineAdmin(admin.TabularInline):
model = Course
fk_name = "student"
class UserAdmin(admin.ModelAdmin):
list_display = ("username", "teacher_courses")
inlines = [TeacherCourseInlineAdmin, StudentCourseInlineAdmin]
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).prefetch_related("teacher_courses")
#admin.display(description='Courses')
def teacher_courses(self, user):
return [c.name for c in user.teacher_courses.all()]
Note that it makes sense to override ModelAdmin.get_queryset() to add a call to prefetch_related() so that Django fetches all related courses in one extra query instead of performing one additional query for every user object.
I have a Comment table on Django Admin:
models.py
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
item = models.ForeignKey(Listing, on_delete=models.CASCADE)
comment = models.TextField(max_length=250)
datetime = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.item}"
admin.py
class CommentInline(admin.TabularInline):
model = Comment
class ItemAdmin(admin.ModelAdmin):
inlines = [
CommentInline,
]
#admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_display = ('item','user','comment','datetime',)
list_filter = ('item',)
And I want to edit this table with the same values item that will display with a single row, and then after clicked on it will display another table contain user comment and datetime .
Thanks so much for any advice to me !!!
If item is a foreign key to one of your other models, you should be able to use an InlineModelAdmin object to create a tabular inline view of the user/comment/datetime using the item's admin view.
See
https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#inlinemodeladmin-objects for reference.
In your case you may end up with something like:
class CommentInline(admin.TabularInline):
model = Comment
fields = ('user', 'comment', 'datetime')
class ItemAdmin(admin.ModelAdmin):
inlines = [
CommentInline,
]
If item is a models.CharField though I don't think you can do it with the Django Admin as provided by Django.
There are two models, a Page model and a Banner model, which are manyToMany related.
The parameters API is twitched, which returns a list of pages and banners for each page. The Banner model has a field is_show by which you need to additionally filter the list of banners, i.e. in the admin panel, the banner can be selected for the model, but if is_show = False, then you do not need to return it to the API.
views
class PagesListView(generics.ListAPIView,
viewsets.GenericViewSet):
queryset = Page.objects.all()
serializer_class = PageSerializer
models
class Banner(models.Model):
title = models.CharField(verbose_name='Заголовок', max_length=255, null=True, blank=True)
is_show = models.BooleanField(verbose_name='Управление отображением', null=False)
pages = models.ManyToManyField(
Page, blank=True, related_name='banners')
class Page(models.Model):
name = models.CharField(max_length=255, null=True, blank=True)
serializers
class BannerSerializer(serializers.ModelSerializer):
class Meta:
model = Banner
fields = '__all__'
class PageSerializer(serializers.ModelSerializer):
banners = BannerSerializer(read_only=True, many=True)
class Meta:
model = Page
fields = '__all__'
The question is how to filter Banner by is_show field?
If you just override the queryset for the view like this:
queryset = Page.objects.filters(banners__is_show=True)
then this is not the desired behavior. In this way, I am filtering the Page list, and I need to "wedge" into filtering the Banner list.
You can do it using related_name with prefetch_related
For ex:
queryset = Page.objects.all().prefetch_related(
Prefetch('banners', queryset=Banner.objects.filter(is_show=True)))
I have the following models:
class Property(models.Model):
user = models.ForeignKey(User)
id = models.CharField(max_length=20, null=True)
class Property_Value(models.Model):
id = models.ForeignKey(Property)
amount = models.DecimalField(max_digits = 10, decimal_places
How do I access the Property_Value.amount via Property on the admin page?
I have this so far...
class PropertyAdmin(admin.ModelAdmin):
list_display = ('id', 'user', 'property_value')
def property_value(self, obj):
return obj.id.amount
class Meta:
model = Property
admin.site.register(Property, PropertyAdmin)
You're interacting, in that instance, with a Property object (since you defined that in the Meta) - syntax is the same as elsewhere in Django. So it would be obj.property_value.amount. If you're using PyCharm, you can get autocomplete for the field by telling PyCharm what 'obj' is, like so:
def property_value(self, obj: Property):
I have three django models and I want to edit item's instances on order's page. Is it possible?
#models.py
class Item(models.Model):
name = models.CharField(max_length = 128)
cart = models.ForeignKey('Cart')
class Cart(models.Model):
number = models.IntegerField()
class Order(models.Model):
cart = models.OneToOneField('Cart')
#admin.py
ItemInline(admin.TabularInline):
model = Item
CartInline(admin.TabularInline):
model = Cart
Order(ModelAdmin):
inlines = (CartInline,) # I need ItemInline here...
Make it so Order is an inline of Cart, rather than the other way around?