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

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

Related

implementing multiple profiles with django-all-auth

Django noob here - I was recently pointed to django-all-auth for registering/handling users, which I'm finding awesome in its near instant setup.
However I'm stumbling at trying to implement multiple user profile models. In reading other answers I've found this to be the closest answer thus far, but not really what I need.
When coding my own basic registration the user would select an account type (basic, pro, elite for example - each being their own profile model). Depending on the link selected the signup form would display both the generic User registration form as well as the profile form of the type chosen by the user.
I know I can go so far as to completely customize all-auth and make something like this work, but I'm hoping to be pointed in a direction that involves less wrecking of the original app. I've thought about having user redirected after signup to choose a profile type, but that seems to be a lot of extra steps.
Thanks for the help!
To extend the basic user class, just subclass AbstractUser. You can find that in the docs. With this you can add the fields your basic user is missing.
Now, you want several types of profiles with different fields, or perhaps the same fields but adding new fields every time.
You can create something like:
class ProfileBase(models.Model):
user=models.OneToOneField(User)
class ProfilePro(ProfileBase):
pro_field=models.SomeField(Foo)
#You can extend ProfilePro here if you want it to include the pro_field
class ProfileElite(ProfileBase):
elite_field=models.someField(Bar)
Once you have these models creating the forms should be easy.
Be aware, when you subclass this way django creates 1 table per model, including on the subclass table only the new fields. This makes necessary a join per level of inheritance so try not to abuse that.
There is a second way to use inheritance:
class ProfileBase(models.Model):
user=models.OneToOneField(User)
class Meta:
abstract=True
If you define the base class as abstract you won't have a table for it, so you can't create objects for that model, but each of your subclasses will be on it's own table. If you do it this way you may need extra logic to handle cases when user changes of type of profile (i.e. went from pro to elite).
To keep this separated from django-allauth, just finish the registration (create a form and in your settings define ACCOUNT_SIGNUP_FORM_CLASS to override all-auth default with your basic info + pick a profile type form) and once your user is logged in, redirect them to their profile to finish the process.

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

Can I make Django admin reflect a hierarchy of models?

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.

Django auth.User

I'm developing web page with many type of users, each with different profiles properties. I would like to use built in auth system but:
a) I want to use django-registration.
b) I can point User.get_profile to only one profile model.
How to accomplish that in nice fashion?
I haven't used django-registration so I don't know what it entails. For the second part of your question one way would be to
Associate an UserProfile with every User
Add different kinds of ProfileProperty classes and link to them from UseProfile using a generic relationship.
I know, it is a bit of a stretch.
I'm not an expert nor in python, django or database but I encountered a somewhat similar issue few weeks ago and on #django someone advised me to use Generic relation to achieve that.
I created a UserProfile model that is liked (through a OneToOnefield) to the "true" profile, and using contrib.content-type and generic relation I'm able to use several distinct porfile types.
Note that should work for you if you don't fear to hit you database one more time on each get_profile().
An alternative would be to create a big table that contain all the field for all the profile type and using some kind of hook (or reimplementing a custom save()) to check the retired fields according the profile type. But it look complicated to me, especially if you want to have a lot of different profile type.
Another alternative could be to create a TextField derivated custom field and use it as a storage for a dictionary that you pickle to it on save and unpickle from it on load. With some hacking you could certainly map some of the model attribute to the dictionary key. That would allow a lot of flexibility.
Free hint for ya : I also use fixtures to test my application and forgot to check if the raw parameter of the post_save signal was True to prevent executing the UserProfile creation when using manage.py loaddata. As I had coded the creation of the "true" profile in my post_save callback the exception what kind of weird until I find out what was happening.
Usefull ressource :
defining a profile
generic relation

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.