I have been tasked with creating Django Models for a hypothetical apartment booking application.
My question is: can I use a model that I've defined, as a field in another model?
For example, I will have one model called "Listing" that represents an apartment being listed.
class Listing(models.Model):
address = models.IntegerField()
owner = models.CharField(max_length=256)
duration = models.DurationField()
price= models.IntegerField()
I also want to have a "Booking" model that represents an apartment once someone has booked it. It will have the exact same info as a Listing, with the addition of the username of the person who booked it. So can I have my Booking model use Listing as a field? And then just have one extra field for the booker's username.
Any other tips/critiques are highly appreciated as I am a complete beginner at Django.
I'm not 100% sure what you mean by use Listing as a field
But to me, you should be looking at the different built-in model relationships that exist in Django.
In your particular case, you will probably want to use a One-to-One relationship like so,
class Listing(models.Model):
address = models.IntegerField()
owner = models.CharField(max_length=256)
duration = models.DurationField()
price= models.IntegerField()
class Booking(models.Model):
listing= models.OneToOneField(
Listing,
on_delete=models.CASCADE,
)
username = models.Charfield()
Now if a user can book more than one apartment at a time, you'll be interested in a ForeignKey relationship like so,
class Listing(models.Model):
address = models.IntegerField()
owner = models.CharField(max_length=256)
duration = models.DurationField()
price= models.IntegerField()
class Booking(models.Model):
listing= models.ForeignKey(
Listing,
on_delete=models.CASCADE,
)
username = models.Charfield()
Note that in both examples I used Charfield for the username, feel free to use whatever Django field you need.
The concept of a model as field is odd. What you can do is establish relationships between models, or to inherit one from the other. Given your situation, you can maybe inherit Booking from Listing:
The docs on this topic.
You'll have something like this:
class Listing(models.Model):
address = models.IntegerField()
owner = models.CharField(max_length=256)
duration = models.DurationField()
price= models.IntegerField()
class Booking(Listing):
#your new fields
Related
I have 4 models: Products (the list of products: freezers, microwaves, tvs and pcs), ProductType (entertainment and home appliances), Credit (a credit is registered on each purchase) and PurchaseReason (the reason why the customer has bought the product).
The PurchaseReason depend on the productType, so the purchaseReason has a foreignKey field productType.
In addition, each credit has a product as foreignKey and a purchaseReason as foreignKey.
Also, I have the ProductReason field as a choice field in the credit model, and I want the options to be set dynamically based on the product field of the credit model.
I'm creating an API so I think this cant be handle with modelForms, but i'm not sure. The hard work would be with the serializers (DRF) and with the django-admin (specially this one because in my product the django admin plays an important role)
What would be the best approach to manage my models in Django?
Here are my models. In credit I'm not sure how to implemente the purchase reason:
class Credit(models.Model):
client = models.ForeignKey('clients.Client', on_delete=models.SET_NULL)
name = models.CharField(max_length=30, null=False, blank=True)
product = models.ForeignKey('product',on_delete=models.SET_NULL)
reason_purchase = models.ChoiceField(????)
class PurchaseReason(models.Model):
product_type = models.ForeignKey(product_type, on_delete=models.CASCADE)
reason = models.CharField(max_length=30, null=False, blank=True)
class ProductType(models.Model):
name = models.CharField(max_length=30, null=False, blank=False)
class Product(models.Model):
model = models.CharField(max_length=30, default=None, null=True)
product_type = models.ForeignKey(product_type, on_delete=models.CASCADE)
When we use the foreign key, we need to mention the model name of that particular model so that we can integrate that particular model in that model as a reference entity. Have a look at this example.
from django.db import models
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
class Article(models.Model):
headline = models.CharField(max_length=100)
pub_date = models.DateField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self):
return self.headline
class Meta:
ordering = ['headline']
you've not mentioned the model name properly. it should be Product in place of 'product' in the Credit class, product field.
use this reference https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/
i think you should be able to use the Foreignkey field properly after this. Although, if you can't, you can share the actual objective. i will help you to write the correct model.
Best wishes :)
I have following models,
class User(models.Model):
name = models.CharField(max_length=255)
...
class InsuranceProfile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
...
class ProductExpertiseMaster(models.Model):
class Meta:
db_table = 'product_expertise_master'
name = models.CharField(max_length=255)
main_category = models.CharField(max_length=255)
class UserProductExpertise(models.Model):
user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
product_expertise = models.ForeignKey(ProductExpertiseMaster, on_delete=models.DO_NOTHING)
So what I am trying to do is I want to filter records based on various fields some of the belong to User model & some of them belong to the InsuranceProfile model.I am filter the records based on User & InsuranceProfile model which is working fine. Now i want to add one more filter which will be based on the UserProductExpertise model.I want to get all the InsuranceProfiles with User details who have some matching condition with product expertise entries in UserProductExpertise model. Any help would appreciated.
You can try like this using __isnull:
InsuranceProfile.objects.filter(user__userproductexpertise__isnull=False)
It will return all the users who has an entry in in UserProductExpertise model. For querying, you need to use all lowercase of the model name, (ie userproductexpertise) and add __isnull at the end of it.
I think you should make some changes in your models before proceeding further.
UserProductExpertise model is the bridge table between ProductExpertiseMaster and User, which provides a many-to-many relationship. If you won't add additional fields to UserProductExpertise model, you can drop it and define user relation in ProductExpertiseMaster model.
If you prefer using seperate model for this relationship, on_delete=models.DO_NOTHING is prone to errors, you can change it to models.CASCADE
Here is an example with many-to-many relation:
class User(models.Model):
name = models.CharField(max_length=255)
class InsuranceProfile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.CharField(("Content"), max_length=500)
class ProductExpertiseMaster(models.Model):
class Meta:
db_table = 'product_expertise_master'
name = models.CharField(max_length=255)
main_category = models.CharField(max_length=255)
user = models.ManyToManyField(User, verbose_name=("Users"), related_name="expertises")
For filtering your query:
InsuranceProfile.objects.filter(user__expertises__isnull=False)
I have the Goal Model and every Goal can have one Mastergoal and or multiple Subgoals.
Goals are connected with Links and every Link can have a different weight.
How do I achieve this with Django?
What I've got so far:
class Goal(models.Model):
user = models.ForeignKey(CustomUser, related_name='goals', on_delete=models.CASCADE)
name = models.CharField(max_length=300)
sub_goals = models.ManyToManyField(to='self', through='Link', symmetrical=False, related_name='master_goals')
class Link(models.Model):
master_goal = models.ForeignKey(Goal, on_delete=models.CASCADE, related_name="sub_links")
sub_goal = models.OneToOneField(Goal, on_delete=models.CASCADE, related_name="master_links")
weight = models.PositiveSmallIntegerField(default=1)
I can't just add an ForeignKey Field on Goal to itself, because every Link can have a different weight.
The solution I've got now works, but it feels wrong. I want to be able to access a Goal's Mastergoal like this: goal.master_goal
In my application there is many-to-one relation, such as one teacher can teach more than one subject. So in admin panel I can't simulate it. Can't add more than one subject:
Here are my codes:
models.py:
class Subject(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=200)
credit = models.IntegerField()
class Teacher(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=100)
email = models.CharField(max_length=100, null=True)
chair = models.ForeignKey(Chair, on_delete=models.CASCADE)
academic_degree = models.CharField(max_length=100)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
You've got it reversed. ForeignKey is Many-to-One with Many being the instances of model where it is defined; you've declared ForeignKey on the Teacher model to Subject model, which means "many teachers can teach only a single subject" -- which should be the other way around.
So define the ForeignKey to the Teacher model on the Subject model. And also do the same for other similar ones.
You are doing it other way around
You should put the 'ForeighKey' relation in 'Subject' model instead of 'Teacher'
class Subject(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=200)
credit = models.IntegerField()
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
This is assuming there is only 1 teacher for a subject. Teacher can have multiple subjects. If there are many teachers for same subject then you need to use ManyToMany() relation.
Django has extremely great support for a attribute related to many other attribute. In your case a single subject could be taught by multiple teacher and multiple teacher can teach single subject. In order to define relationship like above you can leverage ManyToMany relation(this facilate many subject getting associated with single teacher). In case you need one to Many relationship you can use ManyToOne relation.
subject = models.ManyToManyField(subject)
I am fairly new to programming languages, django and database models. So my question is simple I have 3 models in models.py as
class UserProfileInfo(models.Model):
# create relationship with built-in user in admin
user = models.OneToOneField(User)
portfolio_site = models.URLField(blank=True)
class School(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=256)
principal = models.CharField(max_length=256)
location = models.CharField(max_length=256)
class Classroom(models.Model):
school = models.ForeignKey(School, on_delete=models.CASCADE)
class_name = models.CharField(max_length=256)
desc = models.CharField(max_length=256)
And I want to access 'id' from User model. I have tried using
def ClassroomView(request):
classroom_list = Classroom.objects\
.filter(school__id=request.session.get('user_id','0'))\
.filter(user__id=1).values()
class_dict = {'class_records': classroom_list}
return render(request, 'basic_app/classroom_list.html', context=class_dict)
And it gives the following error:
FieldError at /basic_app/class/
Cannot resolve keyword 'user' into field. Choices are: class_name, desc, id, school, school_id
Is there any way that i can access the fields of User model from Classroom model since it is linked by foreign key as Classroom->School->User
Please tell me if I am doing something wrong here any insights and solutions are appreciated!!
Just to recap:
User - UserProfileInfo = 1:1
School - User = 1:N
Classroom - School = 1:N
In other words each user has 1 and only one UserProfile. Each school has 1 user attached and that user can be attached to multiple schools (not sure if this is desired, but that depends on the use case). Each school can have multiple classrooms.
Your goal is to return the list of schools attached to the user. I would do this by:
classroom_list = Classroom.objects.filter(school__user=User.objects.get(pk=0))
or if in a view with request:
classroom_list = Classroom.objects.filter(school__user=request.user)