Stacked Inline with many rows crashing in Django - django

When trying to navigate to 'Add a presentation' in Django admin, I have to wait ~1 minute for the response to render. The problem is that I have ~500 slides in the database and the admin is selecting all the slides three different times to fill in the menues. I am obviously doing something wrong with my model definitions, as I wouldn't expect this amount of data to bring my server to its knees. Any visibility into why I am experiencing this issue with the way I have defined relationships or am using the django admin?
class PresentationTitle(models.Model):
title = models.CharField(max_length=255)
order_number = models.IntegerField(default=0)
def __unicode__(self):
return self.title
class PresentationUser(models.Model):
user = models.OneToOneField(User)
authorized_modules = models.ManyToManyField(PresentationTitle)
class Presentation(models.Model):
title = models.ForeignKey(PresentationTitle)
user = models.ForeignKey(PresentationUser)
presentation_date = models.DateTimeField()
def __unicode__(self):
return self.title.title
class Slide(models.Model):
....
submodule = models.ForeignKey(Submodule)
presentation = models.ManyToManyField(Presentation, through='PresentationSlide')
...
class Meta:
order_with_respect_to = 'submodule'
ordering = ['order']
class PresentationSlide(models.Model):
presentation = models.ForeignKey(Presentation)
slide = models.ForeignKey(Slide)
slide_order = models.IntegerField()
Additionally, my admin contains:
class PresentationSlideInline(admin.StackedInline):
model = PresentationSlide
class PresentationAdmin(admin.ModelAdmin):
inlines = [PresentationSlideInline]
admin.site.register(Presentation, PresentationAdmin)
Understandably, removing just having PresentationAdmin from the admin.site.register makes it load very responsively.

Resolved my issue -- there was another culprit at play: django-debug-toolbar
After removing this from my setup, the admin panel for the Presentation effectively loads.
Thanks to everyone on the interest and the support, be wary of profiling add-ons when you are experience performance issues.

Related

Django admin date time helpers missing

I have a model that includes a datetimefield...
# Create your models here.
class BroadcastNotification(models.Model):
message = models.TextField()
broadcast_on = models.DateTimeField()
sent = models.BooleanField(default=False)
class Meta:
ordering = ['-broadcast_on']
In the admin pages the helpers for that field have gone away.
I don't know what I did to cause it as I didn't test everything after every change. I did do collectstatic fairly recently if that might be the cause.

Django Model with non-unique names

I'm trying to create a simple kanban style board for my task manager app in Django 3.0.3. I've already written the code for projects and tasks, but I'm having trouble figuring out the best way to create the models for the kanban boards. I currently have two models, but can I do this in one for simplicity?
My basic requirement is that every project can have its own board, and each board will have multiple panels. Here is an example:
Board: Development
Backlog
Started
Development
etc...
Board: Operations
Requested
Working
Pending
etc...
With only one model, I'm not sure if this will have the flexibility I need to fully design it. But having multiple models may be too cumbersome to manage for the ultimate user. Here are my current models:
class Board(models.Model):
"""
Defines Kanban boards
"""
name = models.CharField(max_length=25)
slug = models.SlugField(default="")
project = models.ForeignKey(Project, on_delete=models.CASCADE)
tags = TaggableManager(blank=True)
def __str__(self):
board_name = self.project.name + ":" + self.name
return board_name
class BoardPanel(models.Model):
"""
Defines panels in project board
"""
title = models.CharField(max_length=30)
slug = models.SlugField(default="")
board = models.ForeignKey(Board, on_delete=models.CASCADE)
tasks = models.ManyToManyField(Task)
def __str__(self):
panel_name = self.board.name + ":" + self.title
return panel_name
Theoretically you can, but it's not a good approach for any use case. What you've done here is actually the better practice.
Also. in your comment you mention to make it easier to navigate. You can use Django Admin Inlines for that.
Something like this.
class BoardPanelInline(admin.TabularInline):
model = BoardPanel
extra = 0
#admin.register(Board)
class BoardAdmin(admin.ModelAdmin):
list_display = ('name', 'id', 'project',)
inlines = [BoardPanelInline, ]

Django admin cache m2m relation

I have two models:
models.py
class City(models.Model):
title = models.CharField(max_length=255)
show = models.BooleanField(default=True)
class Company(models.Model)
title = models.CharField(max_length=255)
cities = models.ManyToManyField(City, null=True, blank = True)
admin.py
class CompanyAdmin(admin.ModelAdmin):
search_fields = ('title',)
filter_horizontal = ('cities',)
It is about 23000 cities in the database.
When i edit the Company detail in Admin it loads forever!!! Just accessing admin/myapp/company/12/ takes 2-3 minutes - this is horrible.
How can i speed up things and cache City model queryset?
You can use raw_id_fields
class CompanyAdmin(admin.ModelAdmin):
raw_id_fields = ("cities",)
23000 is actually "nothing" for a database.
First, you need to identify the "culprit" of a slowdown, which query is slow. This is where django-debug-toolbar would help a lot. Then, you can run the queries manually with EXPLAIN and see what can be improved - for example, adding indexes could help.
Also, consider using django-cache-machine or johnny-cache packages.
Also see:
Tweaks for making django admin faster

Django Admin Select Objects based on ManyToMany Relationship

I'm working on building a django app that extends the Mezzanine project. Mezzanine has a Gallery app (photos). I'd like to create "portfolio" page that acts as a landing page which has a single image and link to each gallery page.
Each gallery (Gallery) can have multiple images (GalleryImage). I'd like to via the admin select a gallery, then select an image to be displayed. However, I can't seem to figure out what to do.
Here's my model:
class GalleriesThumb(models.Model):
relatedlandingpage = models.ForeignKey(LandingPage)
relatedgallery = models.ForeignKey(Galleries)
thumb = models.ManyToManyField(GalleryImage)
def __unicode__(self):
return self.name
class Galleries(models.Model):
landingpage = models.ForeignKey(LandingPage)
tagline = models.CharField(max_length=100)
galleries = models.ManyToManyField(Gallery)
def __unicode__(self):
return self.name
class LandingPage(models.Model):
gallerytitle = models.CharField(max_length=200)
def __unicode__(self):
return self.name
My admin is something like:
class GalleryInline(admin.InlineModelAdmin)
model = Galleries
model = GalleriesThumb
list_display = galleries
list_display = thumb
class LangingPageAdmin(admin.ModelAdmin):
fieldsets = (
(None, {
'fields': ('gallerytitle')
})
inlines = [GalleryInline,]
I realized that this won't do what i want, but how do I get the list_display on the the images that are related to Galleries. I'm pretty sure it needs to be a method, or am I taking a completing wrong approach if the selections that are made will be defining the content on the page. (I realize that I'm also missing my fields to store the selection in.)
I'm sorry if this a dumb question, but this my first real world attempt an app.
I think this link will resolve your problem
Django 1.2.1 Inline Admin for Many To Many Fields
class GalleryInline(admin.InlineModelAdmin)
model = Galleries.galleries.through

Django admin sharing inlines between apps

I have a few apps in my project that I want to be reusable.
First, I have a base content App, which defines how content can be added to a ContentContainer. This allows other models to inherit ContentContainer to get the ability to show content.
Within the content app, I have a Page model that inherits ContentContainer. In another app called events, I have an Event model that also inherites ContentContainer. Basically, my events app depends on my content app (Which is what I want).
This all works great in modeling. I have this in my content app:
class ContentContainer(admin.ModelAdmin):
#No fields, it just gets referred to by ContentItem
class Meta:
ordering = ['modified']
class ContentItem(TimeStampedModel):
name = models.CharField(max_length=1500)
page_order = models.IntegerField()
container = models.ForeignKey(ContentContainer, blank=True)
#make inheritance know the model type
objects = InheritanceManager()
class Meta:
ordering = [ 'page_order', 'modified', 'name']
def __unicode__(self):
return self.name
def render(self):
return self.name
class TextContent(ContentItem):
text = models.CharField(max_length=5000000)
def render(self):
return '<p>%s</p>' % self.text
Then in my Events app I do this:
class Event(AnnouncementBase, Addressable, ContentContainer):
cost = CurrencyField(decimal_places=2, max_digits=10, blank=True, default=0.00)
start_date = models.DateField(default = datetime.now().date())
start_time = models.TimeField(default = datetime.now().time())
end_date = models.DateField(blank=True, default=None, null = True)
end_time = models.TimeField(blank=True, default=None, null = True)
rsvp_deadline = models.DateTimeField(blank=True, default=None, null = True)
class Meta:
ordering = ['start_date', 'start_time', 'title']
So now events can have content to render.
Here's where things get confusing. I have a slew of inlines defined in admin.py in the content app. They work great there. Also, if I copy an paste them into admin.py in the events app they work there too.
However, I don't want to duplicate code. I want to import the inlines from admin.py into events.py In contents admin.py I have this:
class TextContentInline(admin.TabularInline):
model = models.TextContent
extra = 1
class PageAdmin(ContainerAdmin):
model = models.Page
inlines = [LinkContentInline, TextContentInline]
There are a bunch of these inlines. How can I share them between my admin.py models? If I try to import them in the events admin.py I get an error that says "The model Page is already registered". I've tried about 5 different things I could think of an none of them work. I am wondering if there is no way to do this. Oh I'm using Django 1.3 too.
The "already registered" error happens because when a module is imported, Python executes all the statements in the top level - and one of those is the admin.site.register, which is therefore called multiple times.
It's easy to fix this - just catch the exception and ignore it:
try:
admin.site.register(MyModel, MyModelAdmin)
except admin.sites.AlreadyRegistered:
pass
An alternative is to keep your inline classes in a completely separate module file - admin_inlines.py, perhaps - and import them from there into every admin that needs them.