Django one form / two models - django

I have a very simple model for tracking events:
class Event(models.Model):
description = models.TextField()
location = models.ForeignKey(Location)
start = models.TimeField()
duration = models.IntegerField()
event_date = models.DateField()
creator = models.ForeignKey(User)
and I opted to extract the location in a separate table in order to be able to perform queries:
class Location(models.Model):
city = models.CharField(max_length=20)
address = models.CharField(max_length=30).
What would be the best way to create a form for inserting/updating events, taking into account that the location should be done separately and than linked via ID in the event instance? I wanted to da maybe some autocomplete field for the location address and city, but to keep it on the same form for simplicity?

Define your own widget for the ModelChoiceField in the ModelForm that is generated for the ForeignKey.

Related

Merge Django models into a view

I am attempting to merge and pull data from three Django models into a view. Players and Events relate to each other in the Details model (a player can attend many events) using models.ForeignKey.
In other platforms I would have written a DB View to join tables and the application would query that view.
From what I understand Django does not support data views within Models.
Looking for help on how I would approach this in Django.
class Players(models.Model):
firstName = models.CharField(max_length=255)
lastName = models.CharField(max_length=255)
highSchool = models.CharField(max_length=255)
gradYear = models.IntegerField()
slug = models.SlugField(default="", null=False)
class Events(models.Model):
title = models.CharField(max_length=255)
location = models.CharField(max_length=255)
date = models.DateField()
class Details(models.Model):
event = models.ForeignKey(Events, on_delete=models.CASCADE)
player = models.ForeignKey(Players, on_delete=models.CASCADE)
height = models.IntegerField(default=None, blank=True)
weight = models.IntegerField(default=None, blank=True)
def playerdetail(request,slug):
playerinfo = Details.objects.get(id=1)
template = loader.get_template('playerdetail.html')
context = {
'playerinfo': playerinfo,
}
return HttpResponse(template.render(context, request))
You are actually doing what you needed to do with the code you provided.
When you are invoking a query on a model that connects those two entities (Players,Events), it performs the join when you try to access each of these properties through the foreign key fields.
For example, for accessing the player information (which makes the Django ORM perform the join operation in the background):
# Get the first name of the player
first_name = playerinfo.player.firstName
For filtering and showing in other places, you can use the notation field__subfield
For more information, please read the examples of this website:
https://books.agiliq.com/projects/django-orm-cookbook/en/latest/index.html

Get all related field in Django model

I am struggling to understand how one-to-many and many-to-many relation works in Django model. My schema looks something like this so far, I am open for suggestions to make it better.
A many-to-many relation between users and team. Also, there will be schedules that belong to a particular user of a team.
This is how my model looks like so far,
class Team(models.Model):
tid = models.AutoField(primary_key=True)
team_name = models.CharField(max_length=30)
manager_name = models.CharField(max_length=30)
class Schedule(models.Model):
sid = models.AutoField(primary_key=True)
user = models.OneToOneField(User)
date = models.DateField()
start_time = models.TimeField()
end_time = models.TimeField()
pay_rate = models.CharField(max_length=30)
location = models.CharField(max_length=50)
class BelongsTo(models.Model):
bid = models.AutoField(primary_key=True)
user = models.OneToOneField(User)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
schedule = models.ForeignKey(Schedule, on_delete=models.CASCADE)
Question: I want to get the information of each user, what are their schedules and which team each schedule belongs to. How would I to do it? I have tried BelongsTo.objects.select_related().all(), but it is not working for me.
Note: I am open for suggestions, if something is wrong with my schema or model or the approach, please let me know.
BelongsTo is seems like utility table.So
BelongsTo.objects.all().values('user', 'team__team_name', 'schedule')
Your schema looks almost right, but I would modify it a little bit. In particular, I will change how Schedule is implemented. Instead of having a sid in the User Belongs To join-table, I would include the user and team in the Schedule table as foreign keys.
This is how the Django models should then look like:
class User(models.Model):
username = models.CharField(max_length = 200)
# put other fields like password etc. here
class Team(models.Model):
team_name = models.CharField(max_length=30)
manager_name = models.CharField(max_length=30)
user = models.ManyToManyField("User")
class Schedule(models.Model):
user = models.ForeignKey("User")
team = models.ForeignKey("Team")
date = models.DateField()
start_time = models.TimeField()
end_time = models.TimeField()
pay_rate = models.CharField(max_length=30)
location = models.CharField(max_length=50)
Note the following:
You don't need to have a primary key field in the models because Django adds a primary key field called pk or id automatically.
Note the absence of the User Belongs To model. Django implements join-tables like User Belongs To automatically when you use a ManyToManyField. See the Django docs on many-to-many relationships.
You also don't need on_delete = models.CASCADE on ForeignKey fields, because this is the default behavior.
To see how to get information about users, teams and schedule from this configuration of models, consult the Django documentation on making db queries. It's quite easy.

Django model - set up a "has_many_through" relationship

Looking for advice on setting up this model.
This job board app has Company, Location, and Job. They should have the following relationships:
A Company can have multiple locations
A Company can have multiple jobs
A Job can have only one Company
A Job can have multiple locations, BUT each Location must be valid for the job's Company
I'd like to create a model that reflects these relationships. I think something like this might work:
class Company(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
class Location(models.Model):
is_primary_location = models.BooleanField()
address = models.CharField(max_length=200)
company = models.ForeignKey(Company)
class Job(models.Model):
title = models.CharField(max_length=200)
company = models.ForeignKey(Company)
location = models.ForeignKey(Location)
But I would really like the "Job has Location(s) through Company" relationship to be enforced. The model doesn't enforce it; I think I'd have to filter the valid Locations when data is displayed, and I'd like to avoid that.
Thanks very much!
Take a look at ForeignKey.limit_choices_to.
This allows you to filter the available choices and is enforced in ModelForm. Since you already have the company foreign key in your Job model, you should be able to use that to filter the choices.
I ended up using https://github.com/digi604/django-smart-selects and wrote the model like this. I don't think limit_choices_to works in this case (according to other SO threads)
from smart_selects.db_fields import ChainedForeignKey
class Company(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
class Location(models.Model):
is_primary_location = models.BooleanField()
address = models.CharField(max_length=200)
company = models.ForeignKey(Company)
class Job(models.Model):
title = models.CharField(max_length=200)
company = models.ForeignKey(Company)
location = ChainedForeignKey(
Location,
chained_field="company",
chained_model_field="company",
show_all=False,
auto_choose=True
)

how to conditionally save a form using django multi table inheritance

I have the following form:
class PlaceForm(forms.ModelForm):
class Meta:
model = Place
I have the following models:
class Place(models.Model):
customer = models.ForeignKey(Customer)
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class Restaurant(Place):
serves_hot_dogs = models.BooleanField()
serves_pizza = models.BooleanField()
In my view I want to conditionally save either a Place or a Restaurant depending on the incoming url.
I have tried the following:
if form.is_valid():
place = form.save(commit=False)
place.customer = customer
place.save()
if url_name == 'restaurant':
restaurant = Restaurant(place_ptr_id=place.id)
restaurant.save()
This creates a place from the form and then tries to create a restaurant, but fails with following: (1048, "Column 'customer_id' cannot be null")
This is telling me that a new row for a new place is trying to be inserted and then the restaurant row.
I see a few different options:
Convert the Place to a restaurant and save the additional to the converted object.
Conditionally change the model type of the form to either Place or Restaurant
How can I accomplish saving the different parent and child objects conditionally?
It is related to Django model inheritance: create sub-instance of existing instance (downcast)? which suggests how to add object with existing base class object.
You may want to look at my question: Derived model filefield not available
In nutshell what you have to do is
restaurant = Restaurant(place_ptr_id=place.id)
restaurant.__dict__.update(place.__dict__)
restaurant.save()
You can add null=True and blank=True.
models:
class Place(models.Model):
customer = models.ForeignKey(Customer, null=True, blank=True)
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)

How can I show a ManyToManyField value filtered on the basis of ForeignKey while editing an django model object?

I have four models in my models.py which are:
models.py
class Course(models.Model):
course_code = models.CharField(max_length=100,unique=True)
title = models.CharField(max_length=200)
short = models.CharField(max_length=50)
elective_group = models.CharField(max_length=100)
class Unit(models.Model):
title = models.CharField(max_length=100)
short = models.CharField(max_length=50)
course = models.ForeignKey(Course)
class Pattern(models.Model):
pattern_name = models.CharField(max_length=200)
class ExamSchedule(models.Model):
exam_date = models.DateTimeField()
course = models.ForeignKey(Course)
pattern = models.ForeignKey(Pattern)
**units = models.ManyToManyField(Units)**
I have all these models register with admin site, so that I can use admin functionality for these models.
My problem is when a user creates or edits a ExamSchedule object, I want the units(field) multivalue widget should contains only those values that are associated with a course as every course can have multiple units. So if user creates an Examschedule object and after selecting a course from dropdown the unit widget should only contains those units that related to the course selected.
Thanks
I have used this django plugin to do this exact thing in the admin sections. I believe it also works in the front end as well:
https://github.com/digi604/django-smart-selects