What is better way to have multiple type of member profiles in django - django

I see another question on stackoverflow.com whose title seems similar but that doesnot fulfil my requirements and my users are very different so only different roles will may be not work well. I have scenario of job portal where one type of user is a company which have different attributes different functionality while other is candidate who can show his profile and resume e.t.c., they will have different URLs. So they are totally different but common thing is that they are both Registered users. They will use login forms, they will have change password and I intend to use User class for that purpose.
Actual problem I am facing is about UserProfile class usage. UserProfile is use for profiles but in my case these two users are totally different and need many different things in profile. Also I will may be add more user types in system in future. While in django, we tell about profile is by adding this single model in settings.py
AUTH_PROFILE_MODULE = ‘accounts.userprofile’
So is there a way to do this by using some sort of inheritance or abstract class in django or some other way so that I can get intended functionality and can use django Profiles?

EDIT: Ok, upon further inspection, my previous answer clearly will not work.
I had advocated abstracting the UserProfile class. However, if you do that, you cannot instantiate it, so you're back to square one.
However, you can use Multi-table inheritance to achieve what you want. See this in the docs and this Quora thread that provided the inspiration.
The code I posted before remains largely unchanged, save for the exclusion of the Meta sub-class and the abstract variable.
class UserProfile(models.Model):
# Some Stuff
class CompanyProfile(UserProfile):
# Some more stuff
class CandidateProfile(UserProfile):
# Even more stuff

Related

Django User Class Inheritance

Apologies for this question but I wasn't sure how to get assistance. I'm slowly learning Django (around 2 months in) and trying to work out how to enable user authentication into my website. I've been reading about 3 different ways to do this; OneToOne link to the User class, Subclass the User class or changing the AUTH_USER_MODEL (although not following that one at the momement).
I'm getting myself confused which way to go and would like advice. I'm looking at either OneToOne or creating my own based on the User class. Are there any advantages to one way or the other before I decide which way to go ?
Thanks in advance, there is no where else I can turn.
Regards
Wayne
The answer is, as it often is with vague questions, it completely depends.
Out of the box, you can use the built in auth models to allow users basic access to your sites... that's kind of the whole point of the auth package. If that's all you're looking to do just leverage Auth.User
The question really becomes, what do you need that the built in auth model is not providing you? When you can answer that question, you'll have a better idea of whether you need to override with a custom auth class, simply extend a user profile, or foreign key into other custom data models.

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 - separate authentication backend code from implementation

What is the best way to separate your authentication backend logic from code which is inherently dependent on it?
Here's a common problem: django_auth_ldap does not prepopulate the users table, but rather authenticates against LDAP and adds users to the table as they log in for the first time.
However, say we're writing an app that involves adding members to projects. Users may want to add other users who exist in LDAP but have not logged in before, so you're pretty much required to enter a username in this case and query LDAP and the database to see if that user exists. Again though, if we're writing the app to be reuseable, we'd like the "lookup by username" subroutine to be configurable.
At work we've had two different solutions to the problem which both work fine but they are sort of weird solutions.
Make it so you can write a get_user_by_username function in settings.py which does whatever lookups you want
Give a "appname.modelname" path to a proxy model of auth.User you've created which is expected/forced to have a classmethod which does the same things as get_user_by_username
I think the first one is a little cleaner since it doesn't introduce new types, but it's still a weird thing to have in settings.py.
I suggest writing an abstract base class that encapsulates the expected functionality. This acts somewhat like an interface does in programming languages like C# and Java. Then have a django setting that specifies the class to be used for the get_user_by_username provider.
This means that future developers can put their get_user_by_username implementation anywhere they see fit as long as it is implemented in a class derived from the abstract base class and they point to it in settings.

Is There a Good Way to Forbid Templates Accessing Related Managers Through Model Instances

I need an elegant way of disabling or authorizing related field traversal in Django templates.
Imagine following setup for models.py:
class Person(models.Model):
pass
class Secret(models.Model):
owner = models.ForeignKey(Person, related_name="secrets")
Now imagine this simple view that gives the template QuerySet of all Person instances in the system just so the template could put them in a list.
def show_people(request):
render_to_response("people.html", {people=Person.objects.all()})
Now my problem is that I would not provide the templates myself in this imaginary system and I don't fully trust those who make the templates. The show_people view gives the people.html template the secrets of the Person instances through the related_name="secrets". This example is quite silly but in reality I have model structures where template providers could access all kind of vulnerable data through related managers.
The obvious solution would be not to give models to templates but to convert them in to some more secure data objects. But that would be pain in my case because the system is already quite big and it's up and running.
I think a cool solution to this would be somehow preventing related field traversal in templates. Another solution would be to have such custom related managers that could have access to the request object and filter the initial query set according to the request.user.
A possible solution could be to use a custom model.Manager with your related models.
Set use_for_related_fields = True to force Django to use it instead of the plain manager. modify the manager to filter the data as needed.
also have a look at this:
Django: using managers for related object access (use_for_related_fields docs)
stackoverflow: use_for_related_fields howto, very good explanation here.

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.