Django Model - check validity of the models - python

I am new to Django - ORM and facing issues with creating relations .
The db is SQLite .
I am trying to solve following problem present -
A User will add different Skills to his/her profile .S/He can also
create new skills which were earlier not present and can add to the
profile .
Other users can upvote the skills on user profile - this should be
recorded in Database too .
Uptill not I have created following model
#import from django models module
from django.db import models
# This class will more or less map to a table in the database and defines skills at the application level
class Skill (models.Model):
# this defines a required name that cannot be more than 100 characters.
skill_name = models.CharField(max_length=100,unique=True)
class Meta:
app_label = "wantedly_webapp"
# This class will more or less map to a table in the database and defines the many to many relationship between user-skill, this is our intermediate model
class UserSkill(models.Model):
""" A Model for representing skill in user profile """
unique_together = (('user', 'skill_item'),)
user = models.ForeignKey('UserProfile',on_delete=models.CASCADE)
# Define a foreign key relating this model to the Skill model.
# The parent user will be able to access it's skills with the related_name
# 'all_user_skills'. When a parent is deleted, this will be deleted as well.
skill_item = models.ForeignKey(
Skill,
related_name='all_user_skills', on_delete=models.CASCADE
)
def __str__(self):
"""Return a human readable representation of the model instance."""
return "{}".format(self.skill_item.skill_name)
# this class adds a Many to Many field in existing django-rest auth UserProfile class for user and his/her skills
class UserProfile(models.Model):
user = models.OneToOneField('auth.User',unique=True,on_delete=models.CASCADE)
user_skills = models.ManyToManyField(
Skill,
through='UserSkill',
through_fields=('user','skill_item')
)
class UserSkillUpvotes(models.Model):
unique_together = (('user_skill', 'upvote_by'),)
user_skill = models.OneToOneField('UserSkill',unique=True,on_delete=models.CASCADE)
upvote_by = models.OneToOneField('auth.User',unique=True,on_delete=models.CASCADE)
I have created models now , next I need help on how to test this and update if anything is required for operations like
Adding new skill
Adding existing skill to user profile
Saving up-votes of skill on current user profile by other users etc

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

How to make Django custom user model an abstract class

I have created my own custom user model in django and specified the same in settings.py :
AUTH_USER_MODEL = 'userprofile.User'
After this, I created User as an abstract class since I wanted to have two separate classes derived from this class namely - Vendor and Customer. This will create two separate database tables.
The problem occurs when I created another class - ProductReview. This class needs a foreign key to the user who added the review and this user can be either a Vendor or a Customer. I am not sure how to put this foreign key constraint here, because settings.AUTH_USER_MODEL will not work, as User is an abstract class.
Following is the class structure:
class UserManager(BaseUserManager):
class User(PermissionsMixin, AbstractBaseUser):
class Meta:
abstract = True
class Vendor(User):
class Customer(User):
class ProductReview(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL, related_name='reviews', null=True, blank=True)
Edit - I went ahead with three different tables for each of the models.
For your case I would consider changing my modeling. This how I would do it:
Leave the default User as the auth user model for Django.
Create a Vendor and a Customer class with one-to-one relationship to the User model in order to extend it.
In this way, a you can have a ProductReview to reference a User, who could be either a Vendor or a Customer, or you can reference Customers only if you wish.
See more on Django documentation: Extending the User model.
The declaration of user field in ProductReview model class will map with the USER model. To define whether it is a Vendor or a Customer you need to declare another field probably integer field with mapping declared as
TYPE_OF_USER_MAPPING = {
1: 'Vendor',
2: 'Customer'
}
and then create a query to check in which model Vendor or Customer the original USER is.

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.

Django Relating Model to User

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)

Making a foreign key User model extension in Django required

I am extending the Django User model to include a foreign key pointing at another model like so (just like it says in the Django docs):
models.py:
class Ward(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
# Extending the user model
class WardMember(models.Model):
user = models.OneToOneField(User)
ward = models.ForeignKey(Ward)
def __unicode__(self):
return self.ward.name
admin.py:
class WardMemberInline(admin.StackedInline):
model = WardMember
can_delete = False
verbose_name_plural = 'ward member'
# Define a new User admin
class UserAdmin(UserAdmin):
inlines = (WardMemberInline, )
admin.site.register(Ward)
# Re-register UserAdmin to get WardMember customizations
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
When I create a new user in the admin interface I want this new WardMember.ward extension to be required. Currently it's not enforcing that. Here's what happens:
Create user succeeds without a ward
Create other records as user succeed
Edit user now won't let me save unless there is a ward selected
I'd really like #1 above to fail.
I've tried figuring out how to override save() for User using a proxy object but that's not working. I looked into the pre_save signal but the docs explicitly say that's not for vetoing saves.
What is the right approach?
Additional information:
I'm using 1.4. I see that in 1.5 I can extend the user class but I'm not in a position to update to 1.5 just yet.
I ended up forging ahead with Django 1.5, but I'll leave this here in case someone has a final answer to contribute that works with 1.4.
In django 1.3.1 I use this code and works fine:
from django.contrib.auth.models import User
class FilterSearchQueries(models.Model):
title = models.CharField(max_length=250)
owner = models.ForeignKey(User)
place = models.CharField(max_length=250)
query = models.TextField()

Categories

Resources