Integrate Django Models with a User Account - django

Does anyone have a list of things they do to associate some model with a user?
I.e. if a blog entry has a user, you have to do a few things:
- Add a foriegnkey field
- Make the foreign key field editable = False
- On save/load make sure that request.user matches entry.user
This is what I could come up with. Is there an easier way to do this? Anything else to keep in mind?

It may make more sense to associate the model with a user Profile object than to associate directly with User. That way it's easier to connect the model to custom attributes of the user.

That is an appropriate way, although it may be useful to have it editable. The user should be assigned in the view, not pushed through to the model, in order to maintain clean MVP separation.

Related

How to reference a Model from within the User model

The overall use case is that I want to lookup the correct Business for an authenticated User at the start of each view function so that I can look up relevant info for the appropriate Business.
In my app, an User can only be mapped to one Business, and a Business can map to many Users. To create this mapping, I would like to put a foreign key for a Business in the User model. The Django documentation I've read states that creating a custom User model, which this would require, is not necessary for most applications.
Having such a mapping of an User to something else seems like a pretty common use case, so I'm wondering if there is a simpler way to do this that I'm not aware of.
One approach I thought of would be to have a BusinessUserMapping model, which would contain foreign keys to both Businesses and Users. I could then do a lookup of a BusinessUserMapping where the User foreign key matches the current User, but this seems somewhat convoluted.
Any advice on a better way to look up a Business based on the User?

Session or Model Field in Django?

I'm a beginner in Django. When developing an app, I want to fulfill the following functionality: There is some pictures in one webpage. A user can 'like' a picture by clicking a button bellow it. But one user can only like a specific picture once.
Now there seem two methods to do this.
1) Set an attribute in the session. So I when a user click a button, I can check if he has already 'liked' this picutre according to this session.
2) Add a new field in my user's model to record which pictures he has 'liked'.
Then I don't know which one to use. My questions are as follows:
For method (1), session can expire after some time (e.g. 2 weeks).
So for a user who revisits my website after 2 weeks, is it true that
I can not prevent him from re-liking the picture he's already 'liked'
before?
If I want to have access to the info about which pictures a user
has 'liked', is it true that I can only use method (2) to store this
information?
Thanks a lot!
If you want the "favorites" to persist across multiple sessions, then yes, you need to store the data somewhere that isn't volatile. A simple solution is to use a separate model, a LikedPicture for example:
class LikedPicture(models.Model):
user = models.ForeignKey(User, db_index=True)
picture = models.ForeignKey(Picture)
Session expired? No problem, just get the ones they've liked from the model. You could take it a step further and make the related model generic, so you don't have to make a separate model to hold each association, if you have several different models you're going to associate similarly.
Want to make sure the user only favorites something once? Django makes this ridiculously easy with get_or_create():
favorited_picture, created = FavoritedPicture.objects.get_or_create(user=user,
picture=picture, defaults={'user': user, 'picture': picture})
I find this method to be much more straightforward than trying to maintain a comma-separated-field on a model to store the ids of the favorited things.

Does Django store information about who has edited and/or created a record, and if so, where?

Django has an authentication and authorization scheme baked in ('django.contrib.auth') as well as modelforms to generate forms for easy input of data into the database.
I'd like to be able to record who created a record, leveraging django.contrib.auth, with the explicit purpose of limiting editing of that same record to just that user and/or people with an "edit" permission. I know that I could use the #user_passes_test decorator to restrict access to editing my record in some fashion, but I don't know what I would compare the request.user.name to in order to determine if the current user originally created that record.
How much of this do I need to roll on my own? Do I need to capture the name author, save it to the model, and then read it - or is there something already in the framework that would do this for me?
And, if I was to attempt to save the author in a field, how would I go about doing that in such a way as to not let the user edit their own credentials?
There are a couple of apps to do something similar, please check https://www.djangopackages.com/grids/g/model-audit/
About the last questions, to prevent the user not to edit its own credentials, you can mark the field with editable=False so it wont appear in the admin or ModelForms.

DRY approach to add user information without using Auth.user in Django

I'm writing an application where I need to register user information even if the user does not exists (yet) in Django. Basically I need to insert almost every fields used by Auth.user (I don't care about password). I've also created a Profile model connected with a OneToOneField to the Auth.user model and I need to fill in these fileds as well for users that do not exist yet.
If a user will register later to the site (using Auth.user) I will look for him by email and if I will find him I will merge my inserted information and the ones that he provided.
QUESTION:
What is the best approach to implement user persistence without repeating myself in creating models very similar to each other?
I would recommend using a dummy value in either the date_joined or last_login fields for the User model, if you wanted to implement a solution without adding a new field just to serve as an indicator flag.
The potential problem with using the is_active flag is that you may end up wanting to use this flag to "blacklist" or effectively delete an account without actually removing their record from your database (to prevent re-creation of the account with same credentials, etc.) If you start relying on the fact that the password is not set, then if the day ever comes where you want to implement alternative login methods (OAuth) then your password field will not be set in these cases as well (huge conflict).

Should I ForeignKey to Django User or a Profile model?

I'm wondering what people's thoughts are on joining models directly to the auth.User object vs to the user's profile model.
I'm storing some different types of models which my user are adding in my app. App users will search for other users via criteria on these models.
On the one hand, I'm thinking that if I join straight to User then I won't need to do request.user.get_profile() each time I need to grab the User's records, and it doesn't presuppose that a User always has a profile (they do in my app at the mo, but still). This leaves the profile model as just containing the user's contact details.
On the other hand, I imagine I'll most likely need values from the Profile (eg name, location) when I'm looking up these other models.
No doubt either will work, so maybe it doesn't matter, but I just wondered what other people's thoughts were.
Thanks!
Ludo.
I would also recommend creating foreign-keys to the User model. It just makes your life simpler when working with the user object in the view, for one. So, you can do things like request.user.foo_set, etc. without having to go through the profile model.
In general: If you want to make your apps reusable, always create foreign keys to User model.
As you already said, in most cases you will need User as well as Profile instance, so to prevent multiple database queries, use cache.
If reusability isn't relevant, create foreign key to Profile and use select_related() to get User instance with single query.