Table Master and details with same foreign django - django

I am trying to create two models in django, Reservation and DetailsReservation, i need that models has a same userReservation .Example if i create a Reservation with id: 1 and User: 4, when create a Details with Reservation 1, should copy user in userbyReserva
class Reservation(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
userReservation = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
class DetailsReservation(models.Model):
Reservation = models.ForeignKey(Reservation, blank=False, on_delete=models.CASCADE, null=True)
userbyReserva = #same user that do reservate

You can access the user through the Reservation using a method as property. This is the easiest way to do that.
Some notes about the code:
always use a lower case name for the fields and without the camelNaming.
Avoid plurals on the models' name.
I would avoid using default=1 in a ForeignKey. Better raise an error if the relation is not set. (What happen if the User=1 is deleted?)
Do not copy the data if not necessary, you can use properties to access related field. The user is available only if a reservation is related to the DetailReservation object; detail_reservation.user will return None if the reservation is not set.
I don't understand why you created the reservation relation optional from DetailReservation.
Have a look
class Reservation(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(User, on_delete=models.CASCADE, )
class DetailReservation(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
reservation = models.ForeignKey(Reservation, blank=False, related_name='details',
on_delete=models.CASCADE, null=True)
#property
def user(self):
return reservation.user if reservation else return None

Related

Django QuerySets - Related Models

I have a set of related models - main points included below:
class OrganisationDetails(models.Model):
FormFieldOrgID = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
FormFieldOrgCode = models.CharField(max_length=10, verbose_name='Organisation Code',
help_text='Enter organisation identifier', default='NULL', )
FormFieldOrgName = models.CharField(max_length=75, help_text='Enter Organisation Name',
verbose_name="Organisation Name")
class DepartmentDetails(models.Model):
FormFieldID = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
FormFieldDeptName = models.CharField(max_length=75, help_text='Enter Department Name',
verbose_name="Department name") # name for a department
FormFieldDescription = models.CharField(max_length=200, help_text='Enter department description ',
verbose_name="Department description") # describe the department
class OrgDeptLink(models.Model):
FormFieldID = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
FormFieldDeptID = models.ForeignKey(DepartmentDetails, on_delete=models.CASCADE, related_name='DepartmentDetails',
verbose_name='Department', help_text='Select department') # department
FormFieldOrgID = models.ForeignKey(OrganisationDetails, on_delete=models.CASCADE, related_name='SubordinateRole',
verbose_name='Organisation', help_text='Select organisation')
class OIRLinkStakeholders(models.Model):
FormFieldOIRStakeLinkID = models.UUIDField(primary_key=True, default=uuid.uuid4(), editable=False)
FormFieldOIRStakeholderID = models.ForeignKey(DepartmentDetails, on_delete=models.CASCADE,
help_text='Select Internal Stakeholder',
verbose_name='Stakeholder ID') # TODO Set list to Organisation Departments
FormFieldOIR = models.ForeignKey(OIROverview, help_text='Select OIR Document Name', on_delete=models.CASCADE,
verbose_name='OIR ID') # TODO Default to be set to a selected organisation
I would like to get: FormFieldDepartmentName from class DepartmentDetails(models.Model) using pk from Orgdetails - extract from views.py:
def oirdetails(request, pk):
orgdetails = OrganisationDetails.objects.filter(FormFieldOrgID=pk)
oiroverview = OIROverview.objects.filter(FormFieldOrgDetailID=pk)
alldepartments = OrgDeptLink.objects.filter(FormFieldOrgID=pk)
currentstake = OIRLinkStakeholders.objects.filter(
FormFieldOIRStakeholderID__DepartmentDetails__FormFieldOrgID_id__exact=pk)
The variable for currentstake is the one im trying to relate to:
ive include a snapshot of the relationships below
Ive had a look at the documentation - but cant grasp the concept of ORM in django "yet".
ANy advice most welcome
currentstake = OIRLinkStakeholders.objects.filter(
FormFieldOIRStakeholderID__DepartmentDetails__FormFieldOrgID_id__exact=pk)
was correct but in template had to use currentstake.FormFieldOIRStakeholderID_id

How to query reverse foreign key in django?

I am trying to filter queryset for a reverse foreign key.
Here are my two models:-
class BranchModel(basemodel.BaseModel):
company = models.ForeignKey(CompanyModel, on_delete=models.PROTECT)
name = models.CharField(max_length=30, default="Head Office")
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='branch_owner')
class User(AbstractUser):
id = models.UUIDField(
primary_key=True, default=uuid.uuid4, editable=False
)
objects = UserManager()
I want to get all the users of a branch.
I tried to use this queryset:-
User.objects.filter(branchmodel__user=self.request.user)
but it is giving me empty result.
how can i modify this?
I assume you want all branches of user as per your model setup. Below code will gives you all branches of request.user
user=self.request.user
prtnt(user) # to check user in terminal
userbranches=user.branch_owner.all()

IntegrityError Null constraint violation

I have three models in my django app...a members model, an application model and an applications review model.
My members model looks like this...
class Members(models.Model):
TITLES = (
('chairman', 'Chairman'),
('secretary', 'Secretary')
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
title = models.CharField(max_length=10, choices=TITLES, default='secretary')
My Applications model...
class Application(models.Model):
firstname = models.CharField(max_length=20)
middlename = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
dob = DateField()
The applications review model...
class ApplicationsReview(models.Model):
APPLICATION_STATUS = (
('pending', 'Pending Review'),
('approved', 'Approved'),
('rejected', 'Rejected')
)
applicant = models.OneToOneField(Application, on_delete=models.CASCADE, primary_key=True)
chairman = models.ForeignKey(Members, related_name='chairs', on_delete=models.CASCADE)
secretary = models.ForeignKey(Members, related_name='secretaries', on_delete=models.CASCADE)
application_status = models.CharField(max_length=10, choices=APPLICATION_STATUS, default='pending')
status_justification = models.TextField()
date = models.DateTimeField(auto_now_add=True)
When an application is created, I would like its review instantiated as well, hence, I have the following signal right below the applications review model...
# When an application is created, create with it an application review and associate it with the application instance
#receiver(post_save, sender=Application)
def create_application_review(sender, **kwargs):
instance = kwargs['instance']
created = kwargs['created']
if created:
ApplicationReview.objects.create(applicant=instance)
However, when I try to add an application in django admin I get the error
null value in column "chairman_id" violates not-null constraint
DETAIL: Failing row contains (3, pending, 2019-02-08 03:26:04.643452+00, null, null).
The error seems to be as a result of the signal trying to instantiate an ApplicationsReview instance without providing the values for the chairman and secretary. Even setting those to allow null fields doesn't get rid of the error. Is there something I'm missing here?
Creating ApplicationsReview requires you to pass the following details - chairman, secretary, status_justification But while creating ApplicationReview in the signal you are just passing value of applicant, So Django is assuming the values of chairman, secretary, status_justification fields as Null that is why you are getting this error.
If you want to make these field Non-compulsory you can pass null=True, Blank=True while defining the field in the model.
Something like this:
chairman = models.ForeignKey(Members, null=True, blank=True, related_name='chairs', on_delete=models.CASCADE)
# End
You can refer this answer to get more understanding of when to use null=True, blank=True or both.
https://stackoverflow.com/a/8609425/6280433

Storing data in different tables or using bool fields

I have an Article table
class Article(models.Model):
"""
Model to keep articles
"""
ext_id = models.UUIDField(primary_key=True, db_index=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=255, unique=True, db_index=True)
content = models.TextField()
summary = models.TextField()
img_url = models.URLField(max_length=200)
author = models.CharField(max_length=50, blank=True, null=True)
sport = models.ForeignKey('Sport')
posted_on= models.DateTimeField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __unicode__(self):
return "%s by %s" % (self.title, self.author)
A table where I store articles liked by a user :
class LikedArticle(models.Model):
"""
Articles that a user wants to read
"""
ext_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
article = models.ForeignKey(Article)
profile = models.ForeignKey(Profile)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
and unliked :
class UnlikedLikedArticle(models.Model):
"""
Articles that a user does not want to read
"""
ext_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
article = models.ForeignKey(Article)
profile = models.ForeignKey(Profile)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
Now here, both the tables liked and unliked, are structurally the same.
I find it better to store it like this instead of storing say a bool field called is_liked because I exactly know what data I am storing. So I don't have to query a huge set of articles when I know that I am only interested in LikedArticle.
Is this the correct approach ? I am only confused because structurally they look the same and something doesn't feel right about this design.
the best approach that i recommend is to use one table and add is_liked field. (and add index to this field, so you get high performance queries)
but if still you want to use your approach with 2 table, then you need to fix your design.
use one abstract model that has all fields, and the Like and Unlike tables inherit from the abstract model
class ActionOnArticle(Model):
your fields here..
class Meta:
abstract = True
class LikedArticle(ActionOnArticle):
class UnLikedArticle(ActionOnArticle):
I think is_liked is not a good option if you want to save other information per profile, like that: who liked what and when and so on. If you want to lose those info so my suggestion is to use many to many relationship and the article model will be something like that:
class Article(models.Model):
"""
Model to keep articles
"""
ext_id = models.UUIDField(primary_key=True, db_index=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=255, unique=True, db_index=True)
content = models.TextField()
summary = models.TextField()
img_url = models.URLField(max_length=200)
author = models.CharField(max_length=50, blank=True, null=True)
sport = models.ForeignKey('Sport')
posted_on= models.DateTimeField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
likes = models.ManyToManyField(Profile)
unlikes = models.ManyToManyField(Profile)
def __unicode__(self):
return "%s by %s" % (self.title, self.author)
https://docs.djangoproject.com/en/1.8/topics/db/examples/many_to_many/
While if you want to save the info mentioned at the beginning of my reply, I think #Eyal answer is fine
I'd use the "is_liked" BooleanField and filter on it to just get the liked or disliked articles. Filtering on a BooleanField (add db_index=True on the field options) will be extremely fast with any decent database so you are very unlikely to get a noticable performance increase using separate tables even if they were huge.

Django model related field set

I've got a small problem I can't seem to figure out.
I've got the following model:
class UserWhale(models.Model):
currencyPair = models.ForeignKey('currencies.CurrencyPair', verbose_name='Currency Pair')
currency = models.ForeignKey('currencies.Currency', verbose_name='Source Currency')
currencyTarget = models.ForeignKey('currencies.Currency', related_name='whale_currency_target_rel', verbose_name='Target Currency')
userBankAccount = models.ForeignKey(UserBankAccount, verbose_name='Deposit Bank Account')
whale_fee_percentage = models.DecimalField(max_digits=11, decimal_places=2)
whale_amount = models.DecimalField(max_digits=11, decimal_places=2)
whale_matched = models.DecimalField(max_digits=11, decimal_places=2)
priority = models.IntegerField()
user = models.ForeignKey('auth.User', related_name='whale_relation_user', editable=False)
created_by = models.ForeignKey('auth.User', editable=False)
created = models.DateTimeField(auto_now_add=True, editable=False)
modified = models.DateTimeField(auto_now=True, editable=False)
history = audit.AuditTrail()
When I output the following:
{{ request.user.userwhale_set.count }}
It always outputs as zero even tho the current user has data in that table. The "user" and "created_by" fields are always different so I'm wondering whether or not the code above is using the "created_by" relationship instead of the "user" relationship. If so, how do I specify which one to use?
Many thanks
Ben.
You have specified the related_name property on the user foreignkey, so you should call that name: request.user.whale_relation_user.count.