Django Relating Model to User - python

I want to relate the Model of the Note in my web app with the user that created it .I guess the relation should be Many-to-One.So that i can then filter data by user.Help my the right code , explain , do you thing this is the right method to use in order to have separate data for each user.I really want your opinion on that.
class Note(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
cr_date = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(........) <----- should be something like that

You can add that as foreign key to user model,
#if you are using user model provided by django contrib
from django.contrib.auth.models import User
class Note(models.Model):
#user other fields
owner = models.ForeignKey(User)

Related

Do i need to update AUTH_USER_MODEL in my settings.py?

I am creating my own users, Restaurant and Customer. I have extended the AbstractUser class and then created a OneToOneField field for each user. I am wondering if I need to add the AUTH_USER_MODEL in my settings.py. And also wondering what that does exactly...
What I was planning on doing was adding to my settings.py:
AUTH_USER_MODEL = 'myapp.Customer','myapp.Restaurant'
Do I have the right idea here?
My models.py:
class User(AbstractUser):
is_restaurant = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
class Restaurant(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
restaurant_name = models.CharField(max_length=50)
def __str__(self):
return self.restaurant_name
class Customer(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
address = models.CharField(max_length=200)
def __str__(self):
return self.user.get_full_name()
No. AUTH_USER_MODEL isn't expecting a tuple, so this won't work.
In any case, Restaurant and Customer are not your user model; your subclassed User is. That's what you should be putting in that setting.
I would suggest create single user table instead of three different tables and add type as restaurant, customer, admin etc. And add only one table into settings file. this won't lead any further issues authentication etc. Having single user table is always robust. In your case having three tables seems not good to maintain.
========== UPDATE ===========
Create model for user named as CustomUser (or name which you feel better) and extends to User Model of Django using AbstractBaseUser,PermissionsMixin. like
class CustomUser(AbstractBaseUser): have all fields which user table has already. and add your desired table to bifurcate type of restaurant and
customer have type field with choices option.
For further help you can check section https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#substituting-a-custom-user-model

foreignkey (user) in models

I read the docs and this post... Django - Foreign Key to User model
I followed what it said and I still cannot get it to work. When I try to run the migrations I get this error in the traceback...
django.db.utils.ProgrammingError: column "author_id" cannot be cast automatically to type integer
HINT: You might need to specify "USING author_id::integer".
I just don't know how to go about fixing that error.
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class BlogCategory(models.Model):
'''model for categories'''
title = models.CharField(max_length=30)
description = models.CharField(max_length=100)
class BlogPost(models.Model):
'''a model for a blog post'''
author = models.ForeignKey(User)
date = models.DateField()
title = models.CharField(max_length=100)
post = models.TextField()
Don't use the User model directly.
From the documentation
Instead of referring to User directly, you should reference the user
model using django.contrib.auth.get_user_model()
When you define a foreign key or many-to-many relations to the user model, you should specify the custom model using the AUTH_USER_MODEL setting.
Example:
from django.conf import settings
from django.db import models
class Article(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
If you created a custom User model, you would use setting.AUTH_USER_MODEL, if not you can go ahead an use User model
Referencing Django User model
the column "author_id" doesn't exist, looks like is the same problem from here : Django suffix ForeignKey field with _id , so to avoid this traceback you may use :
author = models.ForeignKey(User, db_column="user")
I do not know the "settings.AUTH_USER_MODEL" approach but a well-known approach and commonly used is the "Auth.User" model. Something like this on your end.
from django.contrib.auth.models import User
class BlogPost(models.Model):
'''a model for a blog post'''
author = models.ForeignKey(User)
date = models.DateField()
title = models.CharField(max_length=100)
post = models.TextField()

Implementing a model for "teams" in django

I want to implement a team feature in django 1.8. (Team as in sports team)
Every user can join up to one team at a time and a team thus can hold many users. Now i am unsure how to define my models.py
I started with this core, but now i am unsure how to make the connection of Team<->User
from django.db import models
class Team(models.Model):
name = models.CharField(max_length=64, unique=True)
description = models.TextField(max_length=1024)
logo = models.ImageField()
from django.contrib.auth.models import User
class Player(models.Model):
user = models.OneToOneField(User)
team = ForeignKey('Team')
Do I now create a second class user_team or do I just add the team as a foreign key to the user? (and if thats the way where would i need to do this?)
Thanks,
Wegi
// edit: I added some code at the bottom. Would this Player model be enough to define the relationship?
For this use case, I will still suggest an alternative using a ManyToMany field, with an intermediate model and model manager.
A quick sample structure looks like this:
from django.db import models
from django.contrib.auth.models import User
class Team(models.Model):
name = models.CharField(max_length=64, unique=True)
description = models.TextField(max_length=1024)
logo = models.ImageField()
players = models.ManyToManyField(User, through='Player')
class PlayerManager(models.Manager):
use_for_related_fields = True
def add_player(self, user, team):
# ... your code here ...
def remove_player(self, user, team):
# ... your code here ...
def trasnfer_player(self, user, team):
# ... your code here ...
class Player(models.Model):
user = models.ForeignKey(User)
team = models.ForeignKey(Team)
other_fields = #...
objects = PlayerManager()
Usage:
Player.objects.add_player(user, team, *other_fields)
You will then be able to get User related Team, for example:
team_with_user = Team.objects.filter(players__name="hello")
user_in_team = User.objects.filter(team__name="world")
Note: I haven't tested the code, so please correct me if I make any mistake above.
The reason why I prefer this way is to abstract away your database logic into application. So in future if there is a need for allowing User joining multiple teams, you can just change the application logic to allow it through the manager.
As suggested by #aumo I solved the problem by adding a user profile model like this:
from django.contrib.auth.models import User
class Player(models.Model):
user = models.OneToOneField(User)
team = models.ForeignKey('Team')
I chose this solution over adding teams as a ManyToMany field inside the Teams class because I am not sure if any more field need to be added to the Player during development.
Thanks to everybody for your help.

Creating many to many relation with AUTH_USER_MODEL in django via intermediary model

I am trying to create the following models. There is a ManyToMany relation from Entry to AUTH_USER_MODEL via the EntryLike intermediate model.
class BaseType(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
creation_time = models.DateTimeField(auto_now_add=True)
last_update_time = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Title(BaseType):
text = models.CharField(max_length=100)
description = models.TextField()
class EntryLike(BaseType):
entry = models.ForeignKey(Entry)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
class Entry(BaseType):
title = models.ForeignKey(Title, on_delete=models.PROTECT)
text = models.TextField()
user = models.ForeignKey(settings.AUTH_USER_MODEL)
liked_by_users = models.ManyToManyField(settings.AUTH_USER_MODEL, through='EntryLike', through_fields=('entry', 'user'))
Running migrations on the above model scheme throws the error: AttributeError:'str' object has no attribute 'meta'.
Any help in resolving this error would be highly appreciated. Am new to Django & Python, but not to Web Development.
The issue is that settings.AUTH_USER_MODEL is almost certainly not a model instance. It's probably a string that constrains the choices another model can make - settings would be a strange place to leave a model definition.
To do a MTM between the user model and your field above you need need to do:
from django.contrib.auth.models import User
class Entry(BaseType):
title = models.ForeignKey(Title, on_delete=models.PROTECT)
text = models.TextField()
user = models.ForeignKey(User)
def __str__(self):
return self.title
I've added the str function so that it gives a more sensible return when you're manipulating it in admin/shell.
I'd also question whether you need the second set of fields (removed here), as you can use select related between the Entry and EntryLike join table, without any duplication of the fields - you can probably go that way, it's just a bit unnecessary.
Lastly, I'd note that the way I'm using it above just uses the default User object that comes with Django - you may wish to customise it. or extend the base class as you've done here with your own models' base class.
(All of this is predicated on AUTH_USER_MODEL not being a model instance - if it is, can you post the model definition from settings.py? )

Django - Need some guidance on how to implement a ManyToMany database

I want the ability to let users indicate what countries they have visited.. my models.py looks something like this:
class User(models.Model):
name = models.CharField(max_length=50)
countries = models.ManyToManyField(Countries)
class Countries(models.Model):
#This is where I don't know what to do.
#The end goal is for the user to be able to check off what countries he/she has visited
You would create the relationship the other way around
class User(models.Model):
name = models.CharField(max_length=50)
class Countries(models.Model):
user = models.ForeignKey(User)
If you are using django's built in User stuff then you only need this.
from django.contrib.auth.models import User
class Countries(models.Model):
user = models.ForeignKey(User)
Relation fields already generate an attribute on the other model for the reverse relation unless explicitly disabled.
You're fine as is w/r/t the ManyToManyField.
Now you'll want to create a form for this model to allow the checking-off to be done by your users.

Categories

Resources