Django User Class Inheritance - django

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.

Related

Why to extend Django User model? Is it bettet than using One-To-One Link With a User Model (Profile)?

this is my first question here, nevertheless S.O. is my main point of reference and support while developing my coding skills with Django.
Thanks on advance to all people who is part of SO!
My main question is: Under your experience, in which situations you needed to extend User Model? is it a common thing to do? ... all tutorials and blogs I have read says ... "for example, if you want to use an email insted a username". But this doesn't sound like a real reason to me, I haven't found other reasons than this.
If I want to use email as username I can create a user-creation form with a field to get username and allowing only emails. This will perfecly solve the problem right?
In my case I followed Django official recommendation:
it’s highly recommended to set up a custom user model, even if the
default User model is sufficient for you. This model behaves
identically to the default user model, but you’ll be able to customize
it in the future if the need arises.
So I did this:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
I'm ready, but ready for what? Please enlight me.
The second part of my question is: Let's imagine in the future I want to register more information about the users of my blog (country, gender, etc.) ... is it possible to create a profile table and point it with 1-to-1 relationship to my extended User model (which does nothing but is ready for the future)? Should I do it now that I have already dropped and created the database again?
Thanks a lot and sorry if I wrote too much.
Best regards,
goka.
If your website need to collect more user information, like, company, telephone, zip code. Also, maybe you need to classify user, like, level_1, level_2, something haven't be define in User model. Then, it's better to create a profile model.
If you already have some user registered, then you add new profile model, it may cause your future coding very messy, like, one year later, you or other software engineer may assume all User have 'profile', and directly use user.profile.something without checking whether profile exists or not or a user, that will throw exception.

How to add fields to third party app model?

I'm working on a web page which uses Django-quiz app. When you install the django-quiz, you can create quizes, questions etc. in Admin.
Unfortunately, there is no way, how to assign Quiz to my model Language so I'm looking for a way, how to add field Language into the model Quiz.
I've tried this but it does not work. I've tried already to create a proxy model with additional field but I realised that it is not possible in proxy models.
from quiz.models import Sitting,Quiz
class QuizAddLanguage(models.Model):
quiz = models.OneToOneField(Quiz)
language = models.ForeignKey(Language)
Do you know what to do to add field to third party app model?
For this time, OneToOne should be enough - for each language there will be one quiz
Since its one to one then you can just define the relationship on your own language class, django by default, will provide you the reverse lookup meaning
language_obj.quiz
quiz_obj.language
will both be valid.
Here is a relevant Django ticket, which was closed with a resolution of "wontfix" six years ago:
https://code.djangoproject.com/ticket/14969
I think this comment provides some good information:
Comments gives you the *right* way to handle this problem -- you define an interface, and make the model itself pluggable. Not all Django's contrib apps follow this approach, but that doesn't mean we bake monkeypatching into the core -- we fix the contrib apps.
django.contrib.comments is now a standalone app, but it still makes itself relatively easy to customize. Here is the relevant documentation:
https://django-contrib-comments.readthedocs.io/en/latest/custom.html
If a third party app doesn't make itself easy to customize, I would suggest asking the developer to update it and point them to the above links for examples on how to go about doing it.

What is better way to have multiple type of member profiles in 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

Django end-user defined fields, how to? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Django dynamic model fields
Good Morning guys!
Scenario is the following. For some models on Django, I would like to allow the end user to define his own fields. It would be great if I could keep all Django awesome features like the ORM, so I can still do calls like field__gte to search on the model, still have field validation according to field type, etc. I've thought about two ways of doing this, and I'm more than open for new suggestions. Any feedback would be VERY appreciated.
The first approach, is the Entity-Attribute-Value ( http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model ), which django already has an app for. See http://code.google.com/p/django-custom-field/
I think this would be an OK solution, but I lose the ability to do "mymodel.objects.filter(custom_field_x=something)". Maybe there's a way to regain the ORM, any ideas? But I've heard so many bad stories about this method that I'm little scared to use it.
The second approach would be to have a database table for each of the users (probably no more than a 1000). I've read django has something in the lines of inspectdb, which actually checks which fields are there and produces the model for you. This could be useful but I think maybe I should store the fields this particular user has created and somehow dinamically tell django, hey, we also have this fields in this model. Is this possible? I know it's generally bad to have different tables for each user, but considering this scenario, how would you guys rate this method, would it be ok to have one table for each user?
The model that requires custom fields is for example Person. They might want a custom field to store address, blood type, or any other thing.
MANY THANKS in advance! Have a nice sunday!
Very similar: How to create user defined fields in Django -- but only talks about the EAV, which I would like to avoid. I'm open for new ideas!
One approach is to use a NoSQL document-based solution such as MongoDB which allows you to store objects that have a fluid structure (no such restrictions as pre-defined columns).
Pros:
No restriction on custom field types, number of types of fields, etc.
Retains ORM functionality (django-mongodb)
Other various benefits of NoSQL - which you can read about online
Avoids EAV
Cons:
Need to setup NoSQL server
Additional knowledge required on NoSQL concepts (documents vs. tables)
You may have to maintain two databases - if you decide not to migrate your entire solution to NoSQL (multi-db)
EDIT:
After reading the comments its worth pointing out that depending on which NoSQL solution you go with, you may not need reversion support. CouchDB, for example has built in support for document versioning.
what about creating another model for storing user_defined_fields?
class UserDefinedField(models.Model):
#..................
user = models.ForeignKey(User)
field_name = models.CharField(max_length=50)
field_value = models.TextField()
Then you can do UserDefinedField.objects.filter(field_name=some_name,field_value=somevalue)

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