Can I make Django admin reflect a hierarchy of models? - django

Assume a Django application with a few models connected by one-to-many relationships:
class Blog(models.Model):
...
class Post(models.Model):
blog = models.ForeignKey(Blog)
...
class Comment(models.Model):
post = models.ForeignKey(Post)
...
Conceptually, they form a hierarchy, a tree-like structure. I want the Django admin to reflect that. In particular:
in a changelist of posts, every post should have a link to the changelist of corresponding comments;
similarly, a post’s edit page should link to the changelist of comments from the top-right buttons area;
when I open that list of related comments, it needs to reflect the relationship in the breadcrumbs (something like: Posts › “Hello world” › Comments) and, ideally, also in the URL (post/123/comment/).
This should of course also apply to the other levels of the hierarchy.
Number 1 is pretty easy with a custom list_display entry and using the ?post__id= query to the comments changelist. But this is little more than a hack. Generally Django assumes my three models to be independent, top-level entities.
Is there a straightforward way to accomplish this? I guess I could override a bunch of templates and AdminModel methods, but perhaps there is a better solution for what seems like a common situation?

Are you sure you are not just looking at Django Admin Inline Models ?
There is no way that an automated admin will pick up your relationships, because in an RDBS there can be any number of foreign keys / one to one / many to many relations, and Django does not have a customized hierarchical behavior built in.
You can indeed edit the breadcrumb customizing an admin template if you want.
For relations you might also be interested into django MPTT that allows to make hierarchical model instances. Also see this question: Creating efficient database queries for hierarchical models (django) in that respect.

How is this a common situation? Consider the fact a model can have a virtually unlimited number of foreign key relationships, let alone visa versa. How would the admin 'know' how to represent this data the way a user requires without customizing things?
One would suggest you are used to work with content management systems rather than webframeworks (no pun intended). It's important to notice Django isn't a cms, but a webframework you can built on top of as you see fit. In a nutshell: 'Django is rather clueless and unaware of contextual requirements'.
Although the admin is quite a beast out-of-the-box, it can be hard to customize. There have been quite some discussions whether it should even be part of core. I can only suggest, if customizing things tends to get hacky, you should probably write your own 'admin', it's not that hard.

Related

how can i replicate admin.TabularInline outside of the admin (on the user side?)

Given a mode A and a model B that has a field with a many to many relationship with model A, I am trying to allow users creating an object of model B to also create an object of model A inline/on-the-fly just like TabularInline allows you to do on the admin.
This is a very common problem and the solution is not trivial (at least for the moment). Django admin uses Javascript(jQuery) to do this task. Multiplication of a form requires lots of altering values and IDs etc. But recently people started doing this with htmx. The way it is done is explained in this article from JustDjango thoroughly. There is even a video tutorial about it. I personally like the way they do it. You can give it a try. It feels and looks like in the django admin. If you would like to do it purely in django, you can look up formset_factory

Suggestions for splitting up application?

I am making a site with Django 1.10 (Python 3). The purpose is to track what book I have and which ones i have read.
I want to make simple CRUD pages for a few different models. The different models I have at the moment are: Books, Authors and Publishers. This list will probably grow. I have read about splitting your site into smaller apps. So one app for the books CRUD pages, one for the authors and one for the publishers.
Is this the way intented by Django? If so a question arises. How do we seperate the models? The Books model has fields that depend on Author and Publisher. But since they are in their own app now, how am I supposed to access it? I am not liking the idea of just importing from another app since they are supposed to be seperate apps.
If they are related then don't separate them. Instead of that, you can re-consider your models' structure and build them again.
I do not know exact fields belong to Author and Publisher but you may combine them in to one model. This is just an idea.
Or you just can create tables like Author, Publisher etc.
There is a process named Normalization which favors, basically, creating tables with small amount of columns instead of creating a big one.
Additionally you may view this thread, too.
I want to make simple CRUD pages for a few different models. The
different models I have at the moment are: Books, Authors and
Publishers. This list will probably grow. I have read about splitting
your site into smaller apps. So one app for the books CRUD pages, one
for the authors and one for the publishers.
Personally I think a single app can handle the three models easily.
Is this the way intented by Django? If so a question arises. How do we
seperate the models? The Books model has fields that depend on Author
and Publisher. But since they are in their own app now, how am I
supposed to access it? I am not liking the idea of just importing from
another app since they are supposed to be seperate apps.
In order to access the fields you need to implement a Foreign key relationship. Check the docs here.
If you still think the models shall live in different apps you will need to import them before using them. Say the Book model needs the Author model. What you will need to do is to import the Author model and link it to the book model with a ManytoMany or ForeignKey relationship.:
from django.db import models
from app_authors.model import Author
class Book()models.Model:
author = ForeignKey(Author, null=True, blank = True, verbose_name = 'Author')

Django. Many forms have OneToOne to one specific model. Forms should always be saved with these relations. How to implement efficiently?

I have many models (Customer, Seller, Product etc.), each of them has a set of images (Gallery, OneToOne relationship).
Also, some models (Customer, Seller, Moderator, Administrator) has OneToOne with User that is used for storing credentials.
I want to create and update these related models together.
Of course, simplest way is to use a class-based view and override get, post and form_valid methods. But there are many models having Gallery and User and I intend to follow DRY and code reuse principles and not to alter each view in same way.
Ideally, solution is sophisticated form (or form set) and using of standard class-based views without method overriding. Other option is different form and class-based view mixin.
I thought few hours about mixins but didn't came up with solution. Now I'm trying to do something with some kind of form sets.
In the case of the gallery is recommended to create an app only for that purpose.
On the case of the user the implementation Here's my recommendation:
1 - Create a base User class with all the core functionality your looking for.
2 - Extend the User class for all the other cases with the functionality your looking for.

Django app where you can send application to authorities

I am currently working to write a web app where people fill out the necessary information, and apply to their mentors.
So, at this point, mentors have a model class that is pretty much like the applicant's, so that they can correct the applicant's info without affecting the applicant's original profile.
I will appreciate any helpful comments. Specifically, I am looking for:
-A similar per-exisiting django app that does more or less so I can browse the source.
-Any special Django feature that allows this that I can not aware of.
-General info on how things like these are done in general.
Thank you.
Ad general info)
You would benefit from doing this in a single model (say ApplicationModel), with fields in pairs - field_name_applicant, field_name_mentor.
Then use a CreateView with its fields property set to only the *_applicant fields for the applicant to fill in the applications initially, and an UpdateView with its fields set to the *_mentor fields for the mentor to correct the applicant fields.
Have ApplicationModel.clean() copy all *_applicant field values to their *_mentor counterpart if the later is not set.
Now you have all your business logic in the model where it belongs; quoting a headline in the introduction of Two Scoops of Django:
Fat Models, Helper Modules, Thin Views, Stupid Templates

database design for multiple similar content types

I've worked on multiple sites recently with similar content types but haven't gotten the design I'm looking to achieve.
I have multiple types of content article, interview, video, gallery, blog, etc. All of these models have very similar properties (title, slug, body, pub_date, etc). And since I'm using django and the admin, almost all the admin setting are identical as well. Most will only have one or two additional fields (ie. filename for video, author for blog).
Currents options are
Using single model "Post/Article" and then just have a type_of_content field. This gives me a single model which makes searches easier and faster and its easy to maintain one model. Managers could be used to pull certain types of content.
Have models 'Video, Interview, Audio' subclass a model called "Post/Article". Gains flexibility of working with different models without all the redundacy. Lots of joins though and all the admin code is still duplicated.
Be very redundant and create a separate model for each type of content even though they share the majority of fields. More stuff to maintain, not DRY at all but highest level of flexibility.
Any insight from someone with more experience would be great.
Thank you.
I don't have that much experience with Django, but it sounds like what you want to do is subclass off of an Abstract Base Class. This avoids creating a table for the abstract parent class, so you get the advantage of your option #2 without the need for joins.