Django Admin Fieldsets - django-admin

Trying to understand Django Admin a bit better, but I find the Django documentation a bit lacking sometimes (or perhaps my capacity to understand).
I know you can use fieldsets to control the layout of certain admin pages. What I can't seem to grasp is what the fieldset names are.
If I have the following class
class Demo(model.Model):
name = models.CharField(max_length=150)
address = models.CharField(max_length=150)
city = models.CharField(max_length=50)
zip = models.CharField(max_length=15)
and Admin class as the following
class DemoAdmin(admin.ModelAdmin):
list_display = ('name', 'City')
In this, albeit contrived example, what possible fieldsets could I use?

Try this, and you'll soon see how it looks/works.
class DemoAdmin(admin.ModelAdmin):
list_display = ('name', 'city')
fieldsets = (
('Standard info', {
'fields': ('name')
}),
('Address info', {
'fields': ('address', ('city', 'zip'))
}),
)
When you go to the change-page to edit, you'll get one box "standard info" with the name-box. And you'll get another box that says "address info" with the adress field first, and then the city and zip-fields on the same line after.

Related

How to Add a field in cascade of 2 many to one on Easyadmin 4 Symfony 6

I read and try a lots of things just to add a field witch is in relation.
One Dance have a level (beginner, improver...) and one Level have a Style (Country music, disco...). So for a dance I can get the level and associate style. Dance is MTO with Level, and Level is MTO with Style. It work fine in traditionnel controller and in Dance Index twig I can do
{{ dance.level.style }}
It's work fine.
Impossible for me to do that in EasyAdmin: In Danse Crud Controller
yield AssociationField::new('level');
is naturally working fine but how adding the style name? I'm not familiar with Queribuilder if it's the solution. I read Symfony Documentation easyadmin about unmapped fields but I don't undestand "createIndexQueryBuilder" parameters. If you can help me to progress. Thank's in advance
I don't find examples in stack with Easyadmin 4. And (I'm sorry), documentation is not very clear for me.
Example:
class UserCrudController extends AbstractCrudController
{
// ...
public function configureFields(string $pageName): iterable
{
return [
TextField::new('fullName'),
// ...
];
}
public function createIndexQueryBuilder(SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters): QueryBuilder
{
$queryBuilder = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters);
// if user defined sort is not set
if (0 === count($searchDto->getSort())) {
$queryBuilder
->addSelect('CONCAT(entity.first_name, \' \', entity.last_name) AS HIDDEN full_name')
->addOrderBy('full_name', 'DESC');
}
return $queryBuilder;
}
}
Why we have "entity.first_name" (why entity word and not entityDto...). dump parameters don't give me persuasive results
Easy finally.
You can choice the field you want to be rendered. Basically add __toString in Entity.
In my case just add for a many to many relation:
AssociationField::new('dances')
->setFormTypeOption('choice_label','level.style'),

How do I make dropdown roles in pycord?

As many may know, discord.py has stopped being maintained. As a result of this, I switched over to Pycord.
My question is:
How do I make the dropdown menu do roles?
I looked at the example on the Github Example file for making dropdown menus in Pycord, and I attempted to make a dropdown menu (successfully). However, this only sends a message when an option is selected from the menu. I want to use this menu for adding and removing roles. How would I go about doing that?
class Select(discord.ui.Select):
def __init__(self):
options = [
discord.SelectOption(label="role name", description="Add the Role_Name role"), #These are the labels
discord.SelectOption(label="role name 2", description="Add role name role."),#^
]
super().__init__(placeholder="Waiting for selection...", max_values=1, min_values=1, options=options)#what will be written waiting for a choise
async def callback(self, interaction: discord.Interaction):
if self.values[0] == 'role name': #'role name'must be the same as the label u want the action to happen. Ex: if label name == hi, well uchange role name to hi here
role = interaction.guild.get_role(ROLE_ID_HERE)#add ur role ID here
await interaction.user.add_roles(role)#Basically if the interaction happen, itll add the role role^ to the user
elif self.values[0] == 'role name 2':
rolee = interaction.guild.get_role(ROLE_ID_HERE)#same as up
await interaction.user.add_roles(rolee)
class SelectView(discord.ui.View):
def __init__(self, *, timeout):
super().__init__(timeout=timeout)
self.add_item(Select())
#client.command()
async def droproles(ctx):
select = SelectView(timeout=None)
await ctx.send("Choose ur role here", view=select)
This is the code. If there is an error tell me, i didnt test it, but it should work. If u dont understand something, tell me. U need to understand to be able to re do it sometime

Django admin custom search on custom column

Question:
How can I add the ability to search for items in my custom column Help Text?
FooAdmin View
Code:
Here is a simplified version of the code that I am working with:
models.py (yes this is how the models need to be set up)
class HelpText(models.Model):
help_text = models.CharField(max_length=1000)
def __str__(self):
return self.help_text
class Foo(models.Model):
job_name = models.CharField(max_length=200, blank=False, null=False)
env = models.CharField(max_length=200, blank=False, null=False)
def __str__(self):
return self.job_name
class FooHelpText(models.Model):
foo = models.OneToOneField(Foo, on_delete=models.DO_NOTHING)
help_text = models.ForeignKey(HelpText, on_delete=models.DO_NOTHING)
def __str__(self):
return str(self.help_text)
admin.py
class FooHelpTextInline(admin.TabularInline):
model = models.FooHelpText
#admin.register(models.Foo)
class FooAdmin(admin.ModelAdmin):
search_fields = ['env', 'job_name',]
list_display = ['pk', 'job_name', 'env', '_get_help_text', ]
inlines = [FooHelpTextInline]
def _get_help_text(self, obj):
return obj.foohelptext.help_text
Current behavior:
The current code above allows me to see the associated help_text in a column on FooAdmin. However, I am not able to search by anything in that column.
Not the answer I am looking for:
I know if it was the other way around where the help_text was a ForeignKey on Foo I could do something like foo__help_text, but that is not how my models are set up (and can not change).
Desired behavior:
Use the search box to search for help text (not just env and job_name).
Possible Solution (that I need help with):
I suspect that get_search_results might be what I need, but I don't understand how to implement it for my use case.
UPDATE:
The closest I can get is searching for a number(aka a specific PK that I know exists) and getting that search result. But the query doesn't really make sense. And obviously that is not the desired functionality of a search.
def get_search_results(self, request, queryset, search_term):
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
try:
search_term_as_int = int(search_term)
except ValueError:
pass
else:
queryset |= models.Foo.objects.select_related(
'foohelptext').filter(fooshelptext=search_term_as_int)
return queryset, use_distinct
I just don't understand the Python |= (bitwise OR operator) and why it has to be an integer.
Much easier than I thought. No need for get_search_results.
Simply needed to add it as foohelptext__help_text__help_text as an other item in the search fields.

how to change "xxx object" in django admin result list

Please take a look at this picture:
I am trying to change "business object" text to it's instance name. I wonder if there is an easy way to do that without dealing with django's core code.
This is the model I'm using:
class Business(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
description = models.TextField(blank=True)
industry = models.ManyToManyField(Industry)
class Meta:
verbose_name = 'Business'
verbose_name_plural = 'Businesses'
def __unicode__(self):
return "%s: %s" % (self.id, self.name)
Call the method __str__ instead of __unicode__. See https://docs.djangoproject.com/en/dev/intro/tutorial02/#playing-with-the-api and look for the info box called "__str__ or __unicode__?".
I had the same problem here. As Brenda J. Butler indicated (the link), it looks like if you are using Python 3.x you should define str() instead of unicode.

jQuery datepicker in Django admin without using django forms

I have a datefield named pub_date in my django project. I want to use jQuery datepicker instead of default django datepicker in django admin. But I want to do it without using django forms. Is it possible to do that? I'm giving my code below.
models.py
import datetime
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
date = models.DateField('Registration Date')
pub_date = models.DateTimeField('date published')
def __unicode__(self):
return self.question
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()
was_published_today.short_description = 'Published today?'
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
def __unicode__(self):
return self.choice
admin.py
from django.contrib import admin
from poject.app.models import Poll, Choice
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class PollAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
list_display = ('question', 'pub_date', 'was_published_today')
list_filter = ['pub_date']
search_fields = ['question']
date_hierarchy = 'pub_date'
admin.site.register(Poll, PollAdmin)
admin.site.register(Choice)
Is it possible to use jquery datepicker in the DateField and DateTimeField defined in the above models without using django forms?
If you don't want to create a form widget you can override the datepicker by overriding your admin change_form.html template.
Check out my question Change the default widget for date fields in Django admin about how to do this for all DateField instances.
If you don't want to touch forms, provide your own js/calendar.js and js/admin/DateTimeShortcuts.js - if you want to do this only for a particular model you'll need to override its change_form.html template and replace the default javascript files just there. What the javascript does is look for date(time) fields and insert the datepicker - yours would do the same, just with a different datepicker.

Resources