How to write __str__ func in this case? - python

I have a 'user' model that have a OneToOneField to User Model and another model named 'user_agent' that have a foreign key to 'user' model. How can I use 'first_name' and 'last_name' in the __str__ func?!
class users(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, default='')
user_type = models.ForeignKey(types, on_delete=models.SET_NULL, blank=True, null=True)
mobile = models.CharField(max_length=20)
active_code = models.CharField(max_length=50, blank=True)
date_send_active_code = models.DateField(default=now, blank=True)
count_send_active_code = models.IntegerField(default=0)
token = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class user_agent(models.Model):
user = models.ForeignKey(user_models.users, on_delete=models.CASCADE)
agent = models.ForeignKey(agents, on_delete=models.CASCADE)
parent = models.ForeignKey("self", on_delete=models.CASCADE, default='1')
def __str__(self):
return "(" + self.user.first_name + " " + self.user.last_name + ")"

You want self.user.user.first_name - but I kindly suggest you change your user model name to something like Profile to avoid confusion (and use CamelCase for your models names in general).

def __str__(self):
return "({} {})".format(self.user.first_name, self.user.last_name)
or if you're using python 3, use f strings:
def __str__(self):
return f"({self.user.first_name} {self.user.last_name})"
EDIT: not sure if you're asking about the user or user_agent model, if it's the user model, then just use the code above but with self.first_name and self.last_name instead.
Also, typically python classes are upper case without underscores:
class User(models.Model) and class UserAgent(models.Model)

Related

django getting all objects from select

I also need the field (commentGroupDesc) from the foreign keys objects.
models.py
class commentGroup (models.Model):
commentGroup = models.CharField(_("commentGroup"), primary_key=True, max_length=255)
commentGroupDesc = models.CharField(_("commentGroupDesc"),null=True, blank=True, max_length=255)
def __str__(self):
return str(self.commentGroup)
class Meta:
ordering = ['commentGroup']
class Comment (models.Model):
commentID = models.AutoField(_("commentID"),primary_key=True)
commentUser = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
commentGroup = models.ForeignKey(commentGroup, on_delete=models.CASCADE, null=True)
commentCI = models.ForeignKey(Servicenow, on_delete=models.CASCADE, null=True)
commentText = RichTextField(_("commentText"), null=True, blank=True)
commentTableUpdated = models.CharField(_("commentTableUpdated"), null=True, blank=True, max_length=25)
def __str__(self):
return str(self.commentGroup)
class Meta:
ordering = ['commentGroup']
views.py
comment = Comment.objects.get(pk=commentID)
Here I get the commentGroup fine but I also need commentGroupDesc to put into my form.
At first, it's not a good thing to name same your model field as model name which is commentGroup kindly change field name, and run migration commands.
You can simply use chaining to get commentGroupDesc, also it's better to use get_object_or_404() so:
comment = get_object_or_404(Comment,pk=commentID)
group_desc = comment.commentGroup.commentGroupDesc
Remember to change field and model name first.

How to get a CharField's value as a string inside the model class?

class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='commenter', null=True)
txt = models.CharField(max_length=1000, null=True)
summary = str(txt)[:30] + '...'
How can I get the txt's value as a string and save it in summary? The code above returns something like this as a string: <django.db.models.fields.CharF...
You don't have to save txt to summary unless necessary. You can use a class method or property of a class to get the summary.
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='commenter', null=True)
txt = models.CharField(max_length=1000, null=True)
def get_summary(self):
return str(self.txt)[:30] + '...'
#property
def summary(self):
return str(self.txt)[:30] + '...'

how to create post with different user type (two foreign key for one post model)?

i'm working on a project the scenario : teachers can make course and publish it in Course model and also institute can make course in Course model?
how can i make it automatically choose one of the foreign key fields?
both institutes and teacher can have post
class Institute(models.Model):
courses = GenericRelation(Course)
institute_name = models.OneToOneField(CustomUser,on_delete=models.CASCADE)
institute_id = models.SlugField(unique=True,default=slug_generator(),blank=True)
phone_number = models.CharField(max_length=11)
locations = models.OneToOneField(Location,on_delete=models.DO_NOTHING,default='')
institute_name.is_institute = True
pass...
def __str__(self):
return self.institute_name.username
class Teacher(models.Model):
course = GenericRelation(Course)
teacher = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
teacher_slug = models.SlugField(unique=True,default=slug_generator())
phone_number = models.CharField(max_length=11,default='')
teacher.is_teacher = True
certification = models.ForeignKey(Certification,on_delete=models.CASCADE, blank=True,null=True)
def __str__(self):
return self.teacher.username
class CustomUser(AbstractUser):
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
is_institute = models.BooleanField(default=False)
email = models.EmailField(unique=True)
objects = UserManager()
def __str__(self):
return self.username
class Student(models.Model):
student = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
student.is_student = True
student_slug = models.SlugField(unique=True,default=slug_generator())
def __str__(self):
return self.student.username
Then define:
if user loggedin in user.is_institute
So querying in institute model
else loggedin in user.is_teacher
And then will work on teacher model.
Does this structure fine ?
I've heard that generic foreign keys not working with API
i also tried this , but i dont how to query them
class Course(models.Model):
course_name = models.CharField(max_length=20)
tags = models.ManyToManyField(Category)
time_created = models.DateTimeField(auto_now_add=True)
content_type = models.ForeignKey(ContentType , on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type','object_id')
def __str__(self):
return self.course_name
from django.contrib.contenttypes.models import ContentType
Teacher ,Institute have different fields name
Thanks
I don't think that GenericRelation is something you really need for this.
How about change the structure a little bit. Let's have Course as the main model for the task.
For example
class Course(models.Model):
teacher = models.ForeignKey(Teacher, related_name='courses', on_delete=models.CASCADE, null=True, blank=True)
institute = models.ForeignKey(Institute, related_name='courses', on_delete=models.CASCADE, null=True, blank=True)
# other necessary fields
#property
def is_teacher(self):
return self.teacher is not None
#property
def is_institute(self):
return self.institute is not None
After that you can check if Course is made by institute like
if course_object.is_teacher:
But if you really want to differentiate your users by institute or teacher you'd need to make custom user model, here's the starting point for you https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project
In that case in your Course model you'd have only one field something like author = models.ForeignKey(User, related_name='courses', on_delete=models.CASCADE)
Hope I've got your question right.

Able to add the same user multiple times to the another model

I have a model which adds(assigns) users to the academy (academy user), the issue is I am able to add the same user multiple times to the academy. What am I doing wrong here?
class AcademyPlayer(models.Model):
academy = models.ForeignKey(Academy, on_delete=models.CASCADE)
player = models.ForeignKey('player.Player', on_delete=models.CASCADE)
date_joined = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.player.user.name
I am adding the player.Player model for reference:
class Player(models.Model):
count = models.IntegerField(
_('count'),
null=True,
blank=True
)
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, related_name='player_user')
def __str__(self):
return self.user.email
class AcademyPlayer(models.Model):
academy = models.OneToOneField(Academy, on_delete=models.CASCADE)
player = models.OneToOneField('player.Player', on_delete=models.CASCADE)
date_joined = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.player.user.name
use OneToOneField for this
and dont forget to makemigrations and migrate after this change

Is a self-join on a model in a django app an acceptable pattern?

Apologies if this question is too subjective.
If you are planning to close this question: please comment with a suggestion for a more appropriate place to post.
I'm super new to django and python, and I'm building a test app that keeps track of employees and who their managers are.
I would like to set up the domain model so that there there is only one list of employees, any of which can be managers, and all of which can be managed by any other employee who is designated a manager.
To achieve this, I did a self-join on the Employee model and have an "is_manager" flag to keep track of who is a manager and who isn't (see model below).
Is an acceptable pattern?
I'm worried it violates a design principle I'm not considering and there's some hairy trap that I'm walking into as a noob.
Thank you very much for your time.
models.py for the app:
class OrganizationTitle(models.Model):
def __str__(self):
return "{}".format(self.organization_title_name)
organization_title_name = models.CharField(max_length=150, unique=True)
class ClassificationTitle(models.Model):
def __str__(self):
return "{}".format(self.classification_title_name)
classification_title_name = models.CharField(max_length=150, unique=True)
class WorkingTitle(models.Model):
def __str__(self):
return "{}".format(self.working_title_name)
working_title_name = models.CharField(max_length=150, unique=True)
class Category(models.Model):
def __str__(self):
return "{}".format(self.category_name)
category_name = models.CharField(max_length=150, unique=True)
class Department(models.Model):
def __str__(self):
return "{}".format(self.department_name)
department_name = models.CharField(max_length=150, unique=True)
class Employee(models.Model):
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=150)
org_title = models.ForeignKey(OrganizationTitle, blank=True, null=True, on_delete=models.SET_NULL)
manager = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
manager_email = models.EmailField(max_length=50, blank=True, null=True)
hire_date = models.DateField(blank=True, null=True)
classification_title = models.ForeignKey(ClassificationTitle, blank=True, null=True, on_delete=models.SET_NULL)
working_title = models.ForeignKey(WorkingTitle, blank=True, null=True, on_delete=models.SET_NULL)
email_address = models.EmailField(max_length=250, blank=False, unique=True,
error_messages={'unique': 'An account with this email exist.',
'required': 'Please provide an email address.'})
category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
is_substitute = models.BooleanField(default=False)
department = models.ForeignKey(Department, blank=True, null=True, on_delete=models.SET_NULL)
is_active = models.BooleanField(default=True)
is_manager = models.BooleanField(default=False)
class Meta:
ordering = ('is_active', 'last_name',)
def __str__(self):
return "{}".format(self.first_name + ' ' + self.last_name)
That's perfectly fine.
I would recommend you to specify the related_name to keep your code more explicit:
manager = models.ForeignKey(..., related_name="managed_employees")
so then you can do something like:
bob.managed_employees.all()
Also, there are 2 things I would change (not your question but still regarding the models):
1.The manager_email field is redundant. I would remove it. You already have that information at tom.manager.email_address for example.
2.There are many fields that I would simply rename to name. For example:
class OrganizationTitle(models.Model):
def __str__(self):
return u"{}".format(self.name)
name = models.CharField(max_length=150, unique=True)
No need to call it organization_title_name. That's consistent with the first_name field (not employee_first_name).
Yes, this is an acceptable pattern. This is called a "recursive relationship", or "self referential foreign keys" and is a very common usecase in realworld applications.
Here is django's example supporting this usecase

Categories