I have three models, I want to display users who apply for leave but I don't know how to accomplish that. The relationship between user to new leave is one to many and the leave balance to new leave is many to many and user to balance is one to one. I only want to display data from user and new leave.
class newleave(models.Model):
user=models.ForeignKey(User,default='',on_delete=models.CASCADE)
leave_balance=models.ManyToManyField(Leave_Balance)
leave=(
('annual','annual'),
('sick','sick'),
)
Leave_type=models.CharField(max_length=100,choices=leave,blank=False,default='')
dp=(
('test','test'),
('test1','test1'),
)
department=models.CharField(max_length=100,choices=dp,blank=False,default='')
Start_Date=models.DateField(null=True, blank=False, default=None)
End_Date=models.DateField(null=True, blank=False, default=None)
Total_working_days=models.FloatField(null=True, blank=False, default=None)
def __unicode__(self):
return self.Leave_type
class Leave_Balance(models.Model):
user=models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True,)
Outstanding_balance=models.FloatField(null=True, blank=True, default=None)
Monthly_entitlement=models.FloatField(null=True, blank=True, default=None)
Monthly_consumption=models.FloatField(null=True, blank=True, default=None)
Leave_current_balance= models.FloatField(null=True, blank=True, default=None)
Month=models.CharField(max_length=100,default="",null=True)
Year=models.CharField(max_length=100,default='')
def __unicode__(self):
return self.Year
The simple way to get users that have an entry in the newleave table is
User.objects.filter(newleave_set__isnull=False).distinct()
I would suggest following PEP8 for your code style as it allows programmers familiar with Python to quickly pick up the intentions of the programs that you write.
Class names should use the CapsWord convention - class NewLeave class LeaveBalance
Method names and instance variables should be lowercase words seperated by underscores NewLeave.start_date etc
The solution was quite straight forward but it took me a while to figure it out. I access the User models data via foreign key and Django actually took care of the joins.
views.py
def Allleaves(request):
allleave=NewLeave.objects.all()
return render(request,'allleave.html',locals())
and in the allleave.html, i access the the User info through the foreign key "user"
{% for leave in allleave%}
{{leave.user.first_name}}
{{leave.user.last_name}}
{{leave.Leave_type}}
{{leave.department}}
{%endfor%}
Related
NOTE I am not necessarily asking for code to build this, just ideas on how to do this. Links and blog posts for pointers are welcome.
I am building a rest api.
I have a model
class Showcase(models.Model):
title = models.CharField(max_length=50)
description = models.TextField(null=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="Showcases")
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=255, unique=True)
def __str__(self):
return self.title
I am trying to build a functionality where the user that created a showcase can add users that contributed to the project which is the showcase. I was thinking of making this its own model like this:
class Collaborator(models.Model):
post = models.ForeignKey(Showcase, on_delete=models.CASCADE, related_name="collaborated_showcases")
owner = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, related_name="showcase_owner")
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE, related_name="collaborators")
skill = models.ForeignKey(Skill, on_delete=models.CASCADE, null=True, related_name="creative_type")
role = models.TextField(null=True)
added_on = models.DateTimeField(null=True)
def __str__(self):
return f"{self.user.name} collaborated on {self.post.name}"
The user would have to search for users and then add them as a contributor to the showcase, which is where my brain scrambles a bit.
The other important thing is that I want to be able to randomly go to a user and get ALL the showcases he has contributed to.
As I see it, this structure works fine for your use case, though:
models should always be in singular case (Collaborator)
related_names should be lower case (related_name="showcases")
and I prefer to explicitly spell out all related_names, so I'd add
Collaborator.post related name collaborated_showcases
Collaborator.user related name collaborators
Showcase.user related_name owned_showcases
Then,
To find an user's owned showcases, Showcase.objects.filter(user=user)
To find an user's collaborated showcases, Showcase.objects.filter(collaborators=user) (I think)
I'd suggest having a Collaborator object for the owner user as well, so you can show their role more easily as well as make these queries simpler.
I am little bit comfused. Lets say I have such models.
models.py:
class Company(models.Model):
name = models.CharField(blank=False, null=False)
class Game(models.Model):
developer = models.ForeignKey(Company, on_delete=models.CASCADE)
publishers = models.ManyToManyField(Company)
If I use next code:
current_company = Company.object.get(pk=1)
current_company.game_set.all()
as I understand it return all games of current_company, but what field (developer or publishers) Django used?
But this code wouldn't be valid, for precisely this reason. If you tried to run it, Django would tell you that there was a conflict in the reverse relation.
If you have two relationships pointing to the same model, you need to explicitly set related_name on one of them to avoid this conflict.
I have a django model that looks something like
class Person(models.Model):
name = models.CharField(max_length=100)
favorite_color = models.CharField(max_length=100)
favorite_candy = models.CharField(max_length=100)
and I want to make a template model for it. Basically, I want a model that can have an arbitrary amount of Person's fields filled out. For instance, say I wanted to have a template for Person that likes chocolate - I'd say something like chocolate_template = PersonTemplate(favorite_color='chocolate') and if I wanted someone whose name is Gerald, I could say gerald_template = PersonTemplate(name='Gerald'). The thought is that I could use these template objects to later pre-fill a Person creation form.
My main question is an implementation question. It's totally possible for me to make a template like so
class PersonTemplate(models.Model):
name = models.CharField(max_length=100, blank=True)
favorite_color = models.CharField(max_length=100, blank=True)
favorite_candy = models.CharField(max_length=100, blank=True)
but the code is horrible in that I have to manually copy-paste the contents of the Person class. This means that if I change Person, I have to remember to update PersonTemplate. I was wondering if there's a prettier way to make a 'child' of a model where all of the fields are optional. Setting all of the fields of Person to blank=True and adding an isTemplate field is also a no-no because Person and PersonTemplate should be two different entities in the database. Any thoughts on this?
Yes of course :)
class PersonTemplate(Person):
field = models.CharField(max_length=100, blank=True)
Its mean you have every fields from Person and you can add more specific fields for PersonTemplate
class Person(models.Model):
Already extend from Model, its why you have access to created, modified, id, pk....
What is good its PersonTemplate 'extend' Person who 'extend' Model.
Since Django 1.10 you can overrride field like that :
class PersonTemplate(Person):
favorite_color = models.CharField(max_length=100, blank=True)
favorite_candy = models.CharField(max_length=100, blank=True)
I used inheritance model in my project after changing the model; but I give non-nullable field error. What should I do?
I am using Django 1.7
class Questions(models.Model):
question_category = models.ForeignKey(Course, blank=False)
question_author = models.ForeignKey(Author, blank=False)
question_details = models.CharField(max_length=100, blank=False, default='')
timestamp = models.DateTimeField(auto_now_add=True)
class TypeFive(Questions):
question_title = models.CharField(max_length=100, blank=False, default=generator(5), unique=True, editable=False)
def __str__(self):
return "{}".format(self.question_title)
class TypeFiveChoice(models.Model):
question_choice = models.ForeignKey(TypeFive)
is_it_question = models.BooleanField(default=False)
word = models.CharField(default='', blank=False, max_length=20)
translate = models.CharField(default='', blank=False, max_length=20)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "{} : {}, {}".format(self.question_choice, self.word, self.translate)
After migrations:
You are trying to add a non-nullable field 'questions_ptr' to typefive without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
In order to inherit from Questions in TypeFive, Django needs to add a relation from TypeFive to Questions. For all records in TypeFive that might already be in the database.
Django now doesn't know which question it should relate TopFive to. This is what the migrate command asks you for. You have a few options, but they greatly depend on your use case and whether you are in early development or if there is a production database where this migration has to run later.
I'm in early development and running it on localhost, so iI don't care
about my records. Now, what should I do?
In this case you haven't much to worry about, when migrate asks you type 1 and then press enter. Now add a primary key of a Questions instance that is in your database and then hit enter again.
Django now relates all TypeFive instances that are currently in the database to this question, so you might have to clean that up afterwards (e.g. by editing the TypeFive in Django admin).
#Nick Brady pointed this out in the question above so I don't mean to take credit but I wanted to highlight.
If your new inheritance class is only used for the purpose of being inherited from, you can easily get around this by setting your parent class to abstract.
class Parent(models.model):
Name = models.CharField(max_length=50)
class Meta:
abstract = True
class Child(Parent):
foobar = models.CharField(max_length=50)
class Meta:
db_table = "typenex_taxonomy_nodes"
I have the following sample models:
class Note(models.Model):
text = models.TextField()
author = models.OneToOneField(User)
date_created = models.DateField(auto_now_add=True)
similar_note = models.ForeignKey("self", related_name='similar_note', null=True, blank=True)
Say there are two notes Winner and Loser.
Loser has a field similar_note that points to Winner Note.
When I delete any of the two, both gets deleted, how do I prevent this from happening?
I have tried doing the same from the django admin interface as well, it happens from there as well.
PS: I am using django1.2, please don't advice to upgrade, there are way too many constraints.
As mentioned here:
When Django deletes an object, by default it emulates the behavior of
the SQL constraint ON DELETE CASCADE -- in other words, any objects
which had foreign keys pointing at the object to be deleted will be
deleted along with it.
This cascade behavior is customizable via the on_delete argument to
the ForeignKey
Please check the on_delete parameter for model field:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)