I want to get a timestamp that is represented in milliseconds or seconds in order to convert it to a DateTime javascript object on the frontend. If there is a way to convert this format
"timestamp" : "2020-11-06T10: 51: 10Z" to a javascript DateTime object just tell me. If I need to use a separate serializer for the DateTime, how do I use a serializer in a serializer?
You can override the to_representation method in your serializer if you don't like the default string representation:
class YourSerializer(serializers.ModelSerializer):
class Meta:
model = YourModel
fields = ['id', 'your_datetime_field']
def to_representation(self, instance):
formatted_datetime_field = instance.your_datetime_field.timestamp()
return {'id': instance.id,
'your_datetime_field': instance.formatted_datetime_field}
This will give you the Unix time, in seconds. JavaScript's Date objects work in milliseconds so you can multiply the result by 1000 to make it work on the frontend.
A slightly different but in my opinion more simple solution would be:
date = serializers.SerializerMethodField(method_name='get_date_timestamp')
def get_date_timestamp(self, instance):
return instance.date.timestamp()
I'm using TimeField in my model but I'm not able to fill seconds in wagtail's wagtail.contrib.modeladmin.options.ModelAdmin.
My current ModelAdmins code is:
#modeladmin_register
class ScheduleAdmin(ModelAdmin):
model = ScheduleCell
menu_label = _("Schedule")
menu_icon = 'date'
menu_order = 200
add_to_settings_menu = False
exclude_from_explorer = False
list_display = ('start_time', 'end_time', 'page', 'output_devices')
search_fields = ('page__title', )
current result is
When I'm trying to write seconds to the input manually - wagtail does not allow it.
How to resolve it?
The date chooser widget doesn't support adding seconds, so you'll need to override this to use a basic text input widget instead. You can do this by adding a panels definition to your model (in the next Wagtail release, Wagtail 2.5, it will be possible to define this on the ModelAdmin class too), and specifying the widget there:
from django import forms
from wagtail.admin.edit_handlers import FieldPanel
class ScheduleCell(models.Model):
# ... field definitions here ...
panels = [
# ...
FieldPanel('start_time', widget=forms.TextInput),
FieldPanel('end_time', widget=forms.TextInput),
# ...
]
here is the models page
In this picture, only the title shows up on here, I used:
def __unicode__(self):
return self.title;
here is the each individual objects
How do I show all these fields?
How do I show all the fields in each Model page?
If you want to include all fields without typing all fieldnames, you can use
list_display = BookAdmin._meta.get_all_field_names()
The drawback is, the fields are in sorted order.
Edit:
This method has been deprecated in Django 1.10 See Migrating from old API for reference. Following should work instead for Django >= 1.9 for most cases -
list_display = [field.name for field in Book._meta.get_fields()]
By default, the admin layout only shows what is returned from the object's unicode function. To display something else you need to create a custom admin form in app_dir/admin.py.
See here: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display
You need to add an admin form, and setting the list_display field.
In your specific example (admin.py):
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'price')
admin.site.register(Book, BookAdmin)
If you want to include all but the ManyToManyField field names, and have them in the same order as in the models.py file, you can use:
list_display = [field.name for field in Book._meta.fields if field.name != "id"]
As you can see, I also excluded the id.
If you find yourself doing this a lot, you could create a subclass of ModelAdmin:
class CustomModelAdmin(admin.ModelAdmin):
def __init__(self, model, admin_site):
self.list_display = [field.name for field in model._meta.fields if field.name != "id"]
super(CustomModelAdmin, self).__init__(model, admin_site)
and then just inherit from that:
class BookAdmin(CustomModelAdmin):
pass
or you can do it as a mixin:
class CustomModelAdminMixin(object):
def __init__(self, model, admin_site):
self.list_display = [field.name for field in model._meta.fields if field.name != "id"]
super(CustomModelAdminMixin, self).__init__(model, admin_site)
class TradeAdmin(CustomModelAdminMixin, admin.ModelAdmin):
pass
The mixin is useful if you want to inherit from something other than admin.ModelAdmin.
I found OBu's answer here to be very useful for me. He mentions:
The drawback is, the fields are in sorted order.
A small adjustment to his method solves this problem as well:
list_display = [f.name for f in Book._meta.fields]
Worked for me.
The problem with most of these answers is that they will break if your model contains ManyToManyField or ForeignKey fields.
For the truly lazy, you can do this in your admin.py:
from django.contrib import admin
from my_app.models import Model1, Model2, Model3
#admin.register(Model1, Model2, Model3)
class UniversalAdmin(admin.ModelAdmin):
def get_list_display(self, request):
return [field.name for field in self.model._meta.concrete_fields]
Many of the answers are broken by Django 1.10. For version 1.10 or above, this should be
list_display = [f.name for f in Book._meta.get_fields()]
Docs
Here is my approach, will work with any model class:
MySpecialAdmin = lambda model: type('SubClass'+model.__name__, (admin.ModelAdmin,), {
'list_display': [x.name for x in model._meta.fields],
'list_select_related': [x.name for x in model._meta.fields if isinstance(x, (ManyToOneRel, ForeignKey, OneToOneField,))]
})
This will do two things:
Add all fields to model admin
Makes sure that there is only a single database call for each related object (instead of one per instance)
Then to register you model:
admin.site.register(MyModel, MySpecialAdmin(MyModel))
Note: if you are using a different default model admin, replace 'admin.ModelAdmin' with your admin base class
Show all fields:
list_display = [field.attname for field in BookModel._meta.fields]
Every solution found here raises an error like this
The value of 'list_display[n]' must not be a ManyToManyField.
If the model contains a Many to Many field.
A possible solution that worked for me is:
list_display = [field.name for field in MyModel._meta.get_fields() if not x.many_to_many]
I like this answer and thought I'd post the complete admin.py code (in this case, I wanted all the User model fields to appear in admin)
from django.contrib import admin
from django.contrib.auth.models import User
from django.db.models import ManyToOneRel, ForeignKey, OneToOneField
MySpecialAdmin = lambda model: type('SubClass'+model.__name__, (admin.ModelAdmin,), {
'list_display': [x.name for x in model._meta.fields],
'list_select_related': [x.name for x in model._meta.fields if isinstance(x, (ManyToOneRel, ForeignKey, OneToOneField,))]
})
admin.site.unregister(User)
admin.site.register(User, MySpecialAdmin(User))
I'm using Django 3.1.4 and here is my solution.
I have a model Qualification
model.py
from django.db import models
TRUE_FALSE_CHOICES = (
(1, 'Yes'),
(0, 'No')
)
class Qualification(models.Model):
qual_key = models.CharField(unique=True, max_length=20)
qual_desc = models.CharField(max_length=255)
is_active = models.IntegerField(choices=TRUE_FALSE_CHOICES)
created_at = models.DateTimeField()
created_by = models.CharField(max_length=255)
updated_at = models.DateTimeField()
updated_by = models.CharField(max_length=255)
class Meta:
managed = False
db_table = 'qualification'
admin.py
from django.contrib import admin
from models import Qualification
#admin.register(Qualification)
class QualificationAdmin(admin.ModelAdmin):
list_display = [field.name for field in Qualification._meta.fields if field.name not in ('id', 'qual_key', 'qual_desc')]
list_display.insert(0, '__str__')
here i am showing all fields in list_display excluding 'id', 'qual_key', 'qual_desc' and inserting '__str__' at the beginning.
This answer is helpful when you have large number of modal fields, though i suggest write all fields one by one for better functionality.
list_display = [field.name for field in Book._meta.get_fields()]
This should work even with python 3.9
happy coding
I needed to show all fields for multiple models, I did using the following style:
#admin.register(
AnalyticsData,
TechnologyData,
TradingData,
)
class CommonAdmin(admin.ModelAdmin):
search_fields = ()
def get_list_display(self, request):
return [
field.name
for field in self.model._meta.concrete_fields
if field.name != "id" and not field.many_to_many
]
But you can also do this by creating a mixin, if your models have different fields.
Consider the following model:
class FPModel(models.Model):
# The user who created
author = models.ForeignKey(auth.models.User, null=False)
# The user who last edited
editor = models.ForeignKey(auth.models.User, null=True)
# Create Time
created_at = models.DateTimeField(auto_now_add=True)
# Modify Time
edited_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
I will be auto-populating the author and editor fields from django admin.
When I sync the database I am getting the following error:
(pinax-env)gautam#Aspirebuntu:$
python manage.py syncdb
Error: One or more models did not validate:
FP.fpmodel: Accessor for field 'author' clashes with related field 'User.fpmodel_set'. Add a related_name argument to the definition for 'author'.
FP.fpmodel: Accessor for field 'editor' clashes with related field 'User.fpmodel_set'. Add a related_name argument to the definition for 'editor'.
I am using django 1.2.5 and pinax 0.7.2.
What should I do to solve this?
I found the answer from the docs, specifically here and here.
I have to use
author = models.ForeignKey(auth.models.User , null = False ,related_name="%(class)s_related_author" ) # The user who created
editor = models.ForeignKey(auth.models.User , null = True,related_name="%(class)s_related_editor" ) # The user who last edited
Getting an error with my admin.py file:
'BaseAdmin.fieldsets[1][1]['fields']' refers to field 'publish_on' that is missing from the form.
my class looks like:
class Base(models.Model):
...
publish_on = models.DateTimeField(auto_now=True, db_index=True)
...
My admin.py looks like:
class BaseAdmin(admin.ModelAdmin):
...
fieldsets = [
('Dates', {
'fields': ('publish_on',)
}),
]
if I change out my admin class with 'pass' or just register with the model class then the date time field shows up.
This error is caused by auto_now and also by auto_now_add. To remedy that add
readonly_fields = ("publish_on",)
in your BaseAdmin (only in django 1.2 and newer).
If you do want to use auto_now_add, but then leave open the possibility of changing the date, you could use default=datetime.now in the model field. This sets a default in the admin, but lets the user change it, and it works in inlines.