I've had plenty of experience in Django but I'm very new to the admin app (we usually build everything into the page as per project requirements).
But now I'm working on a project that requires some admin work and I'm stuck on one part.
Say I have Database models - Person, Student, Faculty
Both Faculty and Student 'is a' Person (they inherit those attributes so to speak). How can I show this in the admin view?
So that when someone clicks to add a student they fill out the student only attributes, but also the attributes required the Person model on the same page. Is this possible?
Here's the models, there's also Faculty but it's similar to Student
class Person(models.Model):
last_name = models.CharField(max_length=50)
first_name = models.CharField(max_length=50)
mi = models.CharField(max_length=50)
phone = models.CharField(max_length=20)
cell = models.CharField(max_length=20)
class Student(models.Model):
year = models.CharField(max_length=10)
stud_id = models.IntegerField()
person = models.ForeignKey(Person)
#many to many
Any ideas or further questions would be awesome!
InlineModelAdmin is your answer!
check it out!
Here is the code you need:
class StudentInline(admin.TabularInline):
model = Student
class PersonAdmin(admin.ModelAdmin):
inlines = [
StudentInline,
]
admin.site.register(Person,PersonAdmin)
Another way is to use Django model inheritance like this:
class Person(models.Model):
last_name = models.CharField(max_length=50)
first_name = models.CharField(max_length=50)
mi = models.CharField(max_length=50)
phone = models.CharField(max_length=20)
cell = models.CharField(max_length=20)
class Student(Person):
year = models.CharField(max_length=10)
stud_id = models.IntegerField()
This way, in the Student Admin page, you will get all the fields from Student AND from Person without Inlines. Also Django will deal automatically with the ForeignKey between the 2 tables.
Docs on Model inheritance.
Related
I have models that share many common fields. For example:
class Customer(models.Model):
name = models.CharField()
email = models.CharField()
address = models.CharField()
phone = models.CharField()
city = models.CharField()
state = models.CharField()
country = models.CharField()
wallet = models.FloatField()
class Seller(models.Model):
# same fields from Customer class, except the field wallet
To avoid repeating these fields, I have tried to create classes with these common fields and link using OneToOneField:
class ContactInformation(models.Model):
phone = models.CharField()
email = models.CharField()
class AddressInformation(models.Model):
address = models.CharField()
city = models.CharField()
state = models.CharField()
country = models.CharField()
class Customer(models.Model):
wallet = models.FloatField()
contact_information = models.OneToOneField(ContactInformation)
address_information = models.OneToOneField(AddresssInformation)
class Seller(models.Model):
contact_information = models.OneToOneField(ContactInformation)
address_information = models.OneToOneField(AddresssInformation)
But now it gets very messy if I try to create a ModelForm based on the Customer, as there is only the wallet field in it. To display my other OneToOneFields I have to create multiple forms: a form for the contact information and another for address information, as ModelForms don't simply display these OneToOneFields as a single form. The views get bloated, as I have to validate 3 forms in total and have to manually create the object instances.
Am I missing something here? Should I use inheritance instead? Should I just repeat these fields to have simpler forms and views? Any advice would be greatly appreciated.
Take a look at abstract base classes, it provides a clean way to reuse common fields to multiple tables.
You might consider:
from django.db import models
class CommonUserInfo(models.model)
name = models.CharField()
email = models.CharField()
address = models.CharField()
phone = models.CharField()
city = models.CharField()
state = models.CharField()
country = models.CharField()
class Meta:
abstract = True
class Customer(CommonUserInfo):
wallet = models.FloatField()
class Seller(CommonUserInfo):
pass
I am not sure what the benefit of using a foreign key for address information is unless you have multiple customers/sellers using the same address and the addresses will need to be updated in unison.
What is the process that you follow to create model in Django? Thanks.
The most important part of a model – and the only required part of a model – is the list of database fields it defines. Fields are specified by class attributes. Be careful not to choose field names that conflict with the models API like clean, save, or delete.
Models.py
from django.db import models
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
You can start here Documentation
See also Django Girls Models
I have 2 models.
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class Reservation(models.Model)
person = ForeiginKey(Perrson, on_delete=models.PROTECT)
from_date = models.DateField()
to_date = models.DateField()
I want make reservation.
How make form in order that first field "person" can search person and add found data to form field, if person not exist add new person.
I would suggest you have a look at django smart selects as it might come handy.
Your model would change as:
from smart_selects.db_fields import ChainedForeignKey
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class Reservation(models.Model)
person = ChainedForeignKey(
Person,
chained_field="Person",
chained_model_field="Person",
show_all=False,
auto_choose=True,
sort=True)
from_date = models.DateField()
to_date = models.DateField()
Next you'd create a form and render it in a template. Whenever you select a person in the form reservation field will update automatically.
Then use a view to handle your logic, if person not exist add new person...
I am currently trying to create a health network website in Django.
The idea is that there will be a class called User inside my registration application. One of the states stored inside User is which hospital the user is registered into.
I created another Hospital within the registration app. I want to user that model Hospital as one of the model field for the hospital_used state. How do I do that? Below is a portion of my UML that illustrates the relationship
UML Diagram
Below is a portion of my UML that illustrates the relationship
png
Here is the code I have for it so far. The code where it is encapsulated with an asterisk is what I need help with.
class Hospital(models.Model):
hospital_Name = models.CharField(max_length=150)
def __str__(self):
return "Hospital Name: " + str(self.hospital_Name)
class User(models.Model):
PATIENT = 'Pat'
DOCTOR = 'Doc'
NURSE = 'Nurse'
ADMINISTRATOR = 'Admin'
user_type_choice = {
(PATIENT, 'Patient'),
(DOCTOR, 'Doctor'),
(NURSE, 'Nurse'),
(ADMINISTRATOR, 'Administrator'),
}
name = models.CharField(max_length=50)
dob = models.DateField(auto_now=False)
username = models.CharField(max_length=50)
*preferred_hospital = Hospital(models.CharField(max_length=50))*
patient_type = models.CharField(
max_length=5,
choices=user_type_choice,
)
Thank you StackOverflow Buddies
I would advise you to read this material on tutorials on how to create simple models.
What you want here is to use the ForeignKey method.
name = models.CharField(max_length=50)
dob = models.DateField(auto_now=False)
username = models.CharField(max_length=50)
preferred_hospital = models.ForeignKey(Hospital, on_delete = models.CASCADE)
patient_type = models.CharField(
max_length=5,
choices=user_type_choice,
)
You do not have to use on_delete = models.CASCADE but it is best that you handle what should happen when you delete an Hospital.
Know that you can also have OneToOne, ManyToOne, or ManyToMany fields, that are all described here.
I am trying to add (+) button on the admin page to duplicate a field. So say I have a field for Father/Mother, and in case someone has a step father or a step mother I could hit the plus button on Father/Mother and duplicate the field and update step Father/Mother info.
I want to be able to do this with other fields as well and not just these two.
I am a newbie. So can you please help me with detailed instructions for how to do this please?
I have been trying to source this info for some time now...but :(
Thanks,
Codie
I have a very simple model structure and no forms as of now. In the future I may have some forms.
class _musi(models.Model):
name = models.CharField(max_length=200)
born = models.DateField()
died = models.DateField()
age = models.IntegerField()
reason_of_death = models.CharField(max_length=200)
birthplace = models.CharField(max_length=200)
father = models.CharField(max_length=200)
mother = models.CharField(max_length=200)
You need to use Django Inlines also to work with inline may be you need to make some changes with your models as you did not show your models so i am not sure about this.
You can refer to Inlines
Django Admin Inlines
Edit :
Please add all fields as Foreignkey with your current model _musi .
You should read how to use Foreign Key relationships
For now if you want with fields father and mother then do like below.
class Father(models.Model):
name = models.CharField(max_length=200)
class Mother(models.Model):
name = models.CharField(max_length=200)
class _musi(models.Model):
name = models.CharField(max_length=200)
born = models.DateField()
died = models.DateField()
age = models.IntegerField()
reason_of_death = models.CharField(max_length=200)
birthplace = models.CharField(max_length=200)
father = models.ForeignKey(Father)
mother = models.ForeignKey(Mother)
Please implement same with your other fields which need this functionality.