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

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.

Related

Create fields based on another model

I have a User model with some fields. Some of them will require feedback, are they correctly filled (if not, specific message will be displayed on user profile).
The problem is, how to represent 'invalid' fields in database. My idea is to create another model (call it ExtUser) with OneToOneField to User. And ExtUser should have same fields' names as User, but their types will be all boolean, determining whether field is filled in correctly. For example, if User has a field called email:
email = models.CharField(max_length=100)
ExtUser would have following field:
email = models.BooleanField(default=False)
Here's a problem with this approach. How am I supposed to create fields in ExtUser? Of course I can create them manually, but that would be breaking of DRY principle, and I'm not going to do that. The question is, can I add fields to model dynamically, and have them in database (so I assume it would require to be called before migrate)?
I have django 1.8 and I don't want to use any external modules/libraries.
If someone has an another idea of how to represent that data in database, please add comment, not a reply - as this question is about creating fields dynamically.
You will need to do this manually.
Python does not disallow this behavior; you can take a look at this SO response on dynamically created classes, but Django will not be able to interpret the output. In particular, Django relies on the models to create the SQL tables for the application, and there is essentially no way for this to occur if you model is not statically defined.
In this case, I don't think you have to worry much about DRY; if you need a separate model with fields which happen to be related to, but different from, another model, I think it's probably ok.
Finally, I'm unsure what your goal is, but you could probably define some functions which can determine how "correct" the fields of the user are. This is how I would recommend solving this problem (if it applies).

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 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

Should I use a constraint?

I'm developing a Twitter-like system, and have a model to record who follows who. There are two fields and both fields are foreign keys and point to the User model.
Clearly you wouldn't want a follower-followee record duplicated, so I'm using the unique_together attribute in the inner Meta class, in order that the follower-followee pair is unique. Trying to violate this throws IntegrityError and 500 status code.
This feels like a "second line of defence" as my view and template code doesn't give a user the chance to follow someone twice.
Should I/can I do something similar to ensure you can't follow yourself?
The view and template that lists all users (each with a button to click to follow that user) does not list the currently logged in user, so there should be no opportunity to follow yourself. But I don't have anything equivalent to unique_together.
Dude, no.
I don't know why you're doing this, but assuming it isn't for a uni project with a lunatic professor, you're wasting your time.
That is, if he's not a lunatic he's not going to try and hack the following/followee . And so what if he does?
If its for a startup-idea, then spend less time solving this (trivial) problem and more time working on whatever business model or marketing or whathaveyou thing you need to do.
A little bug isn't going to be a show stopper.
If you're being contracted out, leave it as a bug and get the conteact extended to fix it :)
If you just want to fix this, just do a check in the model or the validation that the follower isn't the same as the followee