Django - Making a Reservation system - python

As a part of a task, I created an "apartment listings" website.
I managed to get that done, but now I need to make a "reservation system" for it.
The basic idea is that a logged in user can select an apartment from the listed apartments, pick a "start_date" and an "end_date" (if the apartment already isn't booked ) and book the apartment.
Im a total Django newbie, and need some pointers in order to start somewhere with this task.
I have an Apartment model which contains all of the Apartments info that I use to print everything out with the template.
I'm using the provided django user models to register / log-in.
What kind of model do I need for the reservation, and how could I connect everything ?
I tried making a reservation model, but I got no idea where to go next.
I'm not asking for you to solve this for me, I'm asking for someone to explain (if possibile in detal) to me how could I go on about achieving this on my own.
this is my apartment model:
class Apartment(models.Model):
title = models.CharField(max_length=200)
address = models.CharField(max_length=200)
city = models.CharField(max_length=100)
state = models.CharField(max_length=100)
zipcode = models.CharField(max_length=20)
description = models.TextField(blank=True)
price = models.IntegerField()
bedrooms = models.IntegerField()
bathrooms = models.DecimalField(max_digits=2, decimal_places=1)
garage = models.IntegerField(default=0)
size = models.IntegerField()
photo_main = models.ImageField(upload_to='photos/%Y/%m/%d/')
photo_1 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
photo_2 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
photo_3 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
photo_4 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
in_rent = models.BooleanField(default=False)
list_date = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.title
Thank you so much !

Your assumption for making a Reservation object would be correct.
You'll want to link those reservations to the Apartment in question. Django supports these kind of relationships through their ForeignKey and ManyToManyField.
These fields support linking of one-to-one, one-to-many, and many-to-many relationships.
In your case, one Apartment can have many Reservations, which means you need to have a field in your Reservation pointing to a single Apartment, which can be done using a ForeignKey
Your model should look something like this:
Reservation(models.Model)
apartment = models.ForeignKey(to=Apartment, related_name='reservations',
on_delete=models.Cascade)
start_date = models.DateField()
end_date = models.DateField()
To retrieve all reservations for an appartment, you can simply use apartment.reservations since we've defined a related_name in the ForeignKey field.
You can even filter for specific dates by doing Reservations.objects.filter(apartment=apartment, start_date__gte=<your_start_date>, end_date__gte<your_end_date>)

Related

How to Compare ManyToManyField to another ManyToManyField

I have a model of Partner
class Partner(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
group = models.OneToOneField(
Group, on_delete=models.DO_NOTHING, blank=True, null=True)
def __str__(self):
return self.name
I have 2 other models one is CustomUser and other is Quote
class CustomUser(AbstractUser):
#...
name = models.CharField(max_length=160, null=True, blank=True)
partner = models.ManyToManyField(
Partner, blank=True)
class Quote(models.Model):
#...
visibility = models.CharField(max_length=10)
partner = models.ManyToManyField(
Partner, blank=True)
Both have a partner field related with ManyToManyField to Partner Model
Now I want to compare them in the views like:
partner field can have multiple partners like partner1, partner2, partner3
how to to find the partners matching to each other inside the Quote and CustomUser model
Lets say, One of the Quote object have set of [partner1 and partner6] in the ManyToManyField and I only want to have access to that quote to users who also have partner1 and partner6 in their partner ManyToManyField set.
So how can I filter and compare them ?
I also read the docs but didn't able to reproduce the solution. help would be appreciated.
Edit : I can explain it a little , lets say From whole set of partner's in the quote if even one partner is matched to set of partners to the CustomUser then CustomUser should also have access to it.
You can .filter(…) [Django-doc] with:
Quote.objects.filter(partner__customuser=my_user)
This will return a QuerySet of Quotes that have at least one Partner in common with my_user.
The same Quote will be returned that many times as there are Partners in common. You can use .distinct() [Django-doc] to avoid that:
Quote.objects.filter(partner__customuser=my_user).distinct()

How can i perform the right reverse query in ManytoMany in Django

I'm trying to perform a reversed query for a manytomany fields in Django, but it keeps gives me nothing, here is my code
models.py
class Product(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=120)
image = models.ImageField(upload_to='products')
branch = models.ManyToManyField(Branch, related_name='branches')
class Branch(models.Model):
area = models.ForeignKey(Area, on_delete=CASCADE)
name = models.CharField(max_length=1200)
phone = models.CharField(max_length=30, null=True, blank=True)
address = models.CharField(max_length=1200, null=True, blank=True)
tax_value = models.DecimalField(decimal_places=2, max_digits=4)
views.py
for branch in product_object.branches.all():
print(branch)
The branch is always nothing !!
For some reason, the related name is not calling it anymore. I called it using the model name (lower cased).
This is how it worked
for branch in product_object.branch.all():
Just to complete your answer above, I think the way you have your model set up is a little misleading and confusing. I think this would improve clarity:
class Product(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
name = models.CharField(max_length=120)
image = models.ImageField(upload_to='products')
branches = models.ManyToManyField(Branch, related_name='products')
Since you have a many to many field, a product can have multiple branches, the attribute name should reflect that
When you use the related_name, this would be if you are going from the m2m object. For example, if you have a branch, you could get all it's products by doing branch.products

Django Form - Filter a list based on Foreign Key Value

So basically I have the following in my models.py
class Company (models.Model):
title = models.CharField(max_length=100)
short = models.CharField(max_length=50,default='NA')
class AccountingGroups(models.Model):
title = models.CharField(max_length=50, unique=True)
description= models.CharField(max_length=150,blank=True)
section = models.ForeignKey(Section, on_delete=models.PROTECT)
class Transaction (models.Model):
description = models.CharField(max_length=100)
date_created= models.DateField(auto_now_add=True)
posting_date = models.DateField()
user=models.ForeignKey(User, on_delete=models.PROTECT)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
account_group = models.ForeignKey(AccountingGroups, on_delete=models.PROTECT)
income_amt = models.DecimalField(max_digits=6, decimal_places=2,default=0)
expenditure_amt = models.DecimalField(max_digits=6, decimal_places=2,default=0)
Now I am displaying the transaction Form on the browser so to log in all the income and expenditure of a particular company. The below is the forms.py file.
class TransactionForm(ModelForm):
#posting_date = DateField(input_formats=['%d/%m/%Y'])
posting_date = DateField(widget=DatePickerInput(format='%d/%m/%Y').start_of('event active days'),
input_formats=('%d/%m/%Y',),
required=False)
class Meta:
model = Transaction
fields = ['description','posting_date','account_group','income_amt','expenditure_amt']
Now the structure of the website is that each each company that i have in my database has a distinct url. When i go to each url i can view/edit or create a new/existing transaction for that particular company. Now what I'm asking if whether I can restrict the form so that it will show only the Accounting Groups for that particular company only rather than displaying all the accounting groups irrespective on which company I m trying to create the transaction on.
If you are looking to display a Company's AccountingGroups (and not transactions), you need a foreign key to filter off of. You currently don't have any in your AccountingGroups table, unless your Section FK links up to Company. Then you just query off that foreign key relationship.
AccountingGroups.objects.filter(section__company_id=pk)
No matter how you do it, you will need to pass in the company_id via your request.

Using Model.objects.all() as a blueprint for a secondary table entry

I am having a bit of trouble with the logic of how this should work so I am hoping it is possible.
I figured out 1 possible solution that is written as an answer below, I will accept it in a few days, but if someone comes up with a better solution, I will negate any answer I post.
Overall I am working on an Apartment Move-Out/Move-In Inspection Application in Django, and in both portions I have universal Locations that must be inspected for each report. I have allowed the InspectionLocations objects to be updated/submitted by clients, which is presenting an issue in how submitted reports should be stored in my Database.
What I want is to use the InspectionLocations table as a blueprint to build an Inspection Report for Move-Ins where the form-fields are generated based on the InspectionLocations objects' location, status, and information attributes/fields.
My issue is right at this point, how do I reference those values as a blueprint to build a report submission when the number of fields in the InspectionLocations can change?
from django.db import models
from apps.units.models import Unit
class Inspections(models.Model):
class Meta:
abstract = True
id = models.AutoField(primary_key=True)
inspection_date = models.DateField()
submitted_by = models.ForeignKey(
'users.CustomUser',
default=None,
null=True,
on_delete=models.SET_NULL,
db_column='submitted_by')
last_update = models.DateTimeField(auto_now=True)
date_added = models.DateTimeField(auto_now_add=True, editable=False)
class MoveInInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
# should have reference to all InspectionLocation items as reference for submission, how?
class MoveOutInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
date_notice_given = models.DateField(blank=True, null=True, default=None)
date_vacated = models.DateField(blank=True, null=True, default=None)
# should have reference to all InspectionLocation items as reference for submission, how?
class InspectionLocations(models.Model):
'''
Defualt Inspection Locations are created when a
client is created using code like this:
InspectionLocation.objects.get_or_create(location='Living Room')
InspectionLocation.objects.get_or_create(location='Dining Room')
InspectionLocation.objects.get_or_create(location='Kitchen')
InspectionLocation.objects.get_or_create(location='Bedroom')
InspectionLocation.objects.get_or_create(location='Bathroom')
InspectionLocation.objects.get_or_create(location='Other')
'''
id = models.AutoField(primary_key=True)
location = models.CharField(max_length=50)
status = models.BooleanField(default=None)
information = models.TextField(default=None, blank=True)
I have tried ManyToMany fields and FKs but I cannot seem to get the logic working as anytime an object references an InspectionLocations object it is universally changing data for every report, which is leading be to the idea that I somehow need to use it as a blueprint.
I didn't post this in my question because it was getting long, but my best option so far seems to be to use a Django JSONField (as I am using Postgres), like so:
from django.contrib.postgres.fields import JSONField
class MoveInInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
data = JSONField()
class MoveOutInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
date_notice_given = models.DateField(blank=True, null=True, default=None)
date_vacated = models.DateField(blank=True, null=True, default=None)
data = JSONField()
To where I store the values of the InspectionLocations object's in a Dictionary

Django ORM relations one-to-many

I have a model:
class Product(models.Model):
title = models.CharField(max_length=200)
url = models.URLField()
pub_date = models.DateTimeField()
votes_total = models.IntegerField(default=1)
image = models.ImageField(upload_to='images/')
icon = models.ImageField(upload_to='images/')
body = models.TextField()
hunter = models.ForeignKey(User, on_delete=models.CASCADE)
Now I'd like to add a functionality of upvoters to know on what products user has already voted. I need this to allow users vote on the one product only once.
Again, to clarify - user can vote on several products but only once on each.
So the relation is one product - many users (upvoters).
I tried to add the next field but cannot make a migration even if default field is provided. Also I tried to clear the database but again cannot make it work.
upvoters = models.ForeignKey(User, on_delete=models.CASCADE, related_name='upvoted')
I suppose it works the next way:
Field to determine upvoted products.
To check if user has been upvoted on product, call: User.upvoted.filter(id=product.id).count() == 1
This means that user has already upvoted on this product.
What's wrong? What should I change to make it work?
You will have to use ManyToMany, but you can use a custom through model to restrict the product/vote combinations.
To Product class, add:
voters = models.ManyToManyField(User, through='ProductVote', related_name='product_voters')
Then add the custom through model:
class ProductVote(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
product = models.ForeignKey(Vote, on_delete=models.CASCADE)
class Meta:
unique_together = ['user', 'product']
If you try to add a vote for the same user/product combination, an IntegrityError will be raised.

Categories

Resources