Let's say I have a two models:
class Member(models.Model):
nickname = models.CharField(max_length=128)
email = models.EmailField()
avatar = models.ImageField(upload_to='photos/')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return f'Member {self.nickname}'
class Dashboard(models.Model):
title = models.CharField(max_length=128)
owner = models.ForeignKey(Member, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Here I create a distinct model for tracking members who can edit dashboards. Can I use Django users for that instead, avoiding creation of my own models?
Yes, you can.
Just use settings.AUTH_USER_MODEL as your related reference as,
from django.conf import settings
class Dashboard(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
# rest of your models
Note: You can also import the built-in User model from django.contrib.auth.models as #ruddra mentioned, But, there will be errors if you were already extended the auth model.
Related
I have a model for my project which is using GenricFroeignKeys for adding Stakeholders to Projects and Reposistories both.
The model is
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
class StakeHolder(models.Model):
"""Model class for Stakeholders of Project and Repos"""
name = models.TextField()
email = models.EmailField()
def __str__(self):
return self.name
class Role(models.Model):
"""This is the model for Role that the stakeholders will have o projects and repos"""
name = models.TextField()
def __str__(self):
return self.name
class ProjectRepoStakeHolder(models.Model):
"""This is a generic models used to define stakeholders on project and repos"""
stake_holder = models.ForeignKey(StakeHolder, on_delete=models.CASCADE)
role = models.ForeignKey(Role, on_delete=models.CASCADE)
limit = models.Q(app_label='pr_reviews', model='repository') | \
models.Q(app_label='pr_reviews', model='project')
# Fields that are mandatory for generic relations
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, limit_choices_to=limit,)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
def __str__(self):
return self.stake_holder.name + "/" + self.role.name + "/" + self.content_object.name
class Project(models.Model):
"""Model class for Project"""
name = models.TextField(unique=True, blank=False, null=False)
uuid = models.UUIDField(unique=True, blank=False, null=False)
is_active = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class Repository(models.Model):
"""Model class for Repository"""
project = models.ForeignKey(Project, on_delete=models.CASCADE, blank=False, null=False)
name = models.TextField(unique=True, blank=False, null=False)
uuid = models.UUIDField(blank=False, null=False)
is_active = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
Now if I have to add a Stakeholder to a Project or a Repository I have to do it by passing object_id (pk of Project or repo)
Like in this Image. I have to pass object id of a repo or project
Is there a way I can add Stakeholders to a Project or Repo by using their names instead, without having to change the pks of project and repo? (Just like how superadmin handles adding FroeigKey relations by a dropdown). Just like this (for ref)
Following is my admin.py file
from django.contrib import admin
from pr_reviews.models import Project, Repository, Role, ProjectRepoStakeHolder, StakeHolder
class ProjectAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'is_active')
class RepoAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'is_active', 'project')
class ProjectRepoStakeholderAdmin(admin.ModelAdmin):
list_display = ('stake_holder', 'role', 'content_object', 'content_type')
admin.site.register(Project, ProjectAdmin)
admin.site.register(Repository, RepoAdmin)
admin.site.register(ProjectRepoStakeHolder, ProjectRepoStakeholderAdmin)
admin.site.register(Role)
admin.site.register(StakeHolder)
Please be polite if you want me to improve my question. I don't wanna get bullied like last time when I posted a question here. (just a newbie developer)
I have a project in which some user can perform CRUD activities. I want to record who did what and when. Currently, I am thinking of making a model
class UserAction(models.Model):
user_id = models.CharField(max_length=100)
action_flag = models.CharField(max_length=100)
class_id = models.CharField(max_length=100)
action_taken_at = models.DateTimeField(default=datetime.now())
and making a function that fills my UserAction table. Is there any better way to do this?
app/models.py:
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
class Action(models.Model):
sender = models.ForeignKey(User,related_name='user',on_delete=models.CASCADE)
verb = models.CharField(max_length=255)
target_ct = models.ForeignKey(ContentType, blank=True, null=True,
related_name='target_obj', on_delete=models.CASCADE)
target_id = models.PositiveIntegerField(null=True, blank=True)
target = GenericForeignKey('target_ct', 'target_id')
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-created',)
def __str__(self):
return self.pk
app/admin.py
from .models import Action
admin.site.register(Action)
How you can use it ?
you can now import this models(Action) inside any of yours views.py.
Example if you have a post and a user likes it.you can just write
Action.objects.create(sender=request.user,verb="likes this post",target=post)
and now when you look at your admin you will see that tartget_id=post.pk
Here I assume that a user is authenticated and you can change it for your own.Happy coding!!!
You can do it by creating a model in
Models.py
class Auditable(models.Model):
ip = models.GenericIPAddressField(null=True)
user_agent = models.CharField(max_length=255, blank=True)
remote_host = models.CharField(max_length=255, blank=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="%(app_label)s_%(class)s_created_by", null=True, blank=True) # this is for web user
modified_at = models.DateTimeField(auto_now=True, blank=True, null=True)
modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="%(app_label)s_%(class)s_modified_by", null=True, blank=True) # this is for web user
class Meta:
abstract = True
def get_fields(self):
list_fields = ['ip', 'user_agent',
'remote_host', 'created_by', 'modified_by']
return [(field.verbose_name, field._get_val_from_obj(self)) for field in self.__class__._meta.fields if field.name not in list_fields and not
(field.get_internal_type() == "DateTimeField" and
(field.auto_now is True or field.auto_now_add is True)) and
field.concrete and (not field.is_relation or field.one_to_one or
(field.many_to_one and field.related_model))]
You can give any class name (i have given auditable). So all you have to do is pass this class (auditable) in your every model instead of models.Model
For Eg:
class Student(Auditable):
By doing this it will add all the auditable fields records in every table you have created.
Hope you may get your answer by doing this.
I have been using a custom user model for my Django user model. Now, I want to create a new member for the model "uuid" which will be a random long unique string for every new user and users that have been created before. How can I do that in model.py ?
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
bio = models.TextField(max_length=500, blank=True)
language = models.CharField(max_length=30, blank=False, default="en-gb")
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
email_confirmed = models.BooleanField(default=False)
picture = models.CharField(max_length=1000, default="")
is_custom_picture = models.BooleanField(default=False)
You could add another field inside your django model called uniqueID
import uuid
uniqueID = models.UUIDField(max_length=255, default = uuid.uuid4)
You could also initialize this to act as the primary_key of your model using primary_key=True argument inside the field constructor.
In Django i have created a model which use USER model data
this holds all user id form database, BUT i it filtered by certain group
userId = models.ForeignKey(User, on_delete=models.CASCADE)
model.py
**from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Review(models.Model):
userId = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100, blank=True)
reviewText = models.TextField(max_length=500, blank=False)
timeStamp = models.DateTimeField(auto_now_add=True, auto_now=False)
def __unicode__(self):#for python <2
return self.name
def __str__(self):#for python 3
return self.name**
form displayed(with all user_id)
If you want to filter foreign key choices, you can use limit_choices_to in your model field like this:
class Review(models.Model):
userId = models.ForeignKey(User, limit_choices_to={'groups__name': 'Your Group Name'}, on_delete=models.CASCADE)
I am using the default User model, and created a custom model called Team. A user can only be on one team, but a team can have many users. Therefore, I must create the ForeignKey field within the User model.
The thing is, I'm using the default User by simply importing User with from django.contrib.auth.models import User
What is the easiest way of adding a ForeignKey field into the default User model? Do I have to extend the default User model?
Or is there a way for me to add a ForeignKey field into Team, and swap the relationship between User and Team?
Honestly when you are working with the default Django user model, it's always better to create a custom user model that you can modify easier. Below is a simple example on how you can modify your User class with the AbtractBaseUser. If you'd like to add a foreign key just use ForeignKey instead of the data types below.
from __future__ import unicode_literals
from django.utils import timezone
from django.contrib.auth.models import (AbstractBaseUser,PermissionsMixin)
from django.db import models
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
username = models.CharField(max_length=7, unique=True)
formattedusername = models.CharField(max_length=11, unique=True, primary_key = True)
first_name = models.CharField(max_length=40)
last_name = models.CharField(max_length=140)
date_joined = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
facility = models.CharField(max_length=140)
jobdescription = models.CharField(max_length=140)
positiondescription = models.CharField(max_length=140)
coid = models.CharField(max_length=5)
streetaddress = models.CharField(max_length=140)
USERNAME_FIELD = 'username'
class Meta:
app_label = 'accounts'
db_table = "user"
# REQUIRED_FIELDS = "username"
def __str__(self):
return "#{}".format(self.username)
In my opinion, the best way of achieving what you want is to use an in-between table. Therefore, you would create your Team model as normal and then create another model with two foreign keys to both User and Team. This is an example, it may change, feel free to change it to your needs.
class Group(models.Model):
group = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(Team, on_delete=models.CASCADE)
class Team (models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
#your other fields