I'm writing a simple to do list whit Django framework. This is the model of Task.
class Task(models.Model):
title = models.CharField(max_length=250)
description=models.CharField(max_length=250)
assigned_to = models.ManyToManyField(User)
creation_date =models.DateField(auto_now=True)
due_date =models.DateField(blank=True, null=True)
completed = models.BooleanField(default=False)
parent_task=models.ForeignKey(Task)
list = models.ForeignKey(List)
I want to create subtasks. But when I migrate occurred this error:
parent_task=models.ForeignKey(Task)
NameError: name 'Task' is not defined
If you want to use the same model for subcategorizing, use self in ForeignKey. For example,
class Task(models.Model):
title = models.CharField(max_length=250)
description = models.CharField(max_length=250)
assigned_to = models.ManyToManyField(User)
creation_date = models.DateField(auto_now=True)
due_date = models.DateField(blank=True, null=True)
completed = models.BooleanField(default=False)
parent_task = models.ForeignKey('self')
list = models.ForeignKey(List)
You need to pass your model name to models.ForeignKey() as a string like below:
parent_task = models.ForeignKey('Task') # Or 'self'
Instead of:
parent_task = models.ForeignKey(Task)
Related
I got this code, but I can't find a way to create a view that retrieve the allergies a patient has.
class Patient(models.Model):
user = models.OneToOneField(User, related_name='patient', on_delete=models.CASCADE)
id_type = models.CharField(max_length=300)
id_number = models.CharField(max_length=300)
creation_date = models.DateField(default=datetime.date.today)
class Allergie(models.Model):
name = models.CharField(max_length=300, default="X")
class PatientAllergies(models.Model):
patient = models.ForeignKey(Patient, related_name="patient_allergies", on_delete=models.CASCADE)
allergie = models.ForeignKey(Allergie, on_delete=models.CASCADE, null=True)
professional_contract = models.ForeignKey(ProfessionalContract, null=True ,on_delete=models.CASCADE)
You can span a ManyToManyField relation over your PatientAllergies model that acts as a junction table:
class Patient(models.Model):
user = models.OneToOneField(User, related_name='patient', on_delete=models.CASCADE)
id_type = models.CharField(max_length=300)
id_number = models.CharField(max_length=300)
creation_date = models.DateField(auto_now_add=True)
allergies = models.ManyToManyField(
'Allergie',
through='PatientAllergies'
)
# …
You can then for a Patient object p with:
p.allergies.all()
An alternative is to filter the Allergie objects with:
Allergie.objects.filter(patientallergies__patient=p)
or with the ManyToManyField:
Allergie.objects.filter(patient=p)
This is a part of models.py in my django app.
class User(models.Model):
user_id = models.AutoField(primary_key=True)
uuid = models.CharField(max_length=32)
name = models.CharField(max_length=10)
phone = models.CharField(max_length=20)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class UserForm(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
access_info = models.CharField(max_length=250)
etc_comment = models.CharField(max_length=250)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class UserAddress(models.Model):
user_address_id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
address_name = models.CharField(max_length=100)
address_name_detail = models.CharField(max_length=100)
address_type = models.CharField(max_length=11)
address_coord = models.PointField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
I am using MySQL database and linked it to django database.
My question is how to get all three data together just in a single query.
As I know, I have to use django's prefetch_related or select_related method to get them together like this
objs = User.objects.select_related('userform').get(user_id=1)
But, what about getting them from three model classes?
Please, let me know if you have any idea.
I am new to Django project and wanted to know what is the best practice for designing models.
I am working on creating a small project which will have collections of stories in a category and subcategorical manner. I am tagging it as Django because I wanted to also verify the scope of app.
Apps:
index, genre
Design:
Index
Genre
|-- Story
|--Section
|-- Chapters
|--Paragraph
|-- title
|-- text
|-- highlights
genre.models.py
class Story(models.Model):
stry = models.CharField(max_length=256,unique=True)
id =models.AutoField(primary_key=True)
def __str__(self):
return self.stry
class Section(models.Model):
stry = models.ForeignKey(Story,on_delete=models.CASCADE)
name = models.CharField(max_length=256)
desc=models.TextField()
id =models.AutoField(primary_key=True)
slug = models.CharField(max_length=240, null=True, blank=False)
created_at = models.DateTimeField(auto_now_add=True, null=False)
updated_at = models.DateTimeField(auto_now=True, null=False)
class Chapter(models.Model):
sec = models.ForeignKey(Section,on_delete=models.CASCADE)
name = models.CharField(max_length=256)
desc=models.TextField()
id =models.AutoField(primary_key=True)
slug = models.CharField(max_length=240, null=True, blank=False)
created_at = models.DateTimeField(auto_now_add=True, null=False)
updated_at = models.DateTimeField(auto_now=True, null=False)
class Paragraph(models.Model):
chap = models.ForeignKey(Chapter,on_delete=models.CASCADE)
title = models.CharField(max_length=120, null=True, blank=False)
subtitle = models.CharField(max_length=180, null=True, blank=False)
slug = models.CharField(max_length=240, null=True, blank=False)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True, null=False)
updated_at = models.DateTimeField(auto_now=True, null=False)
The genre can have many stories, and each section can have many chapters and a similar pattern
Question:
Is there a better design model that I can work on?
Can divide these into different apps or have 1 app for each genre or
include genre as a model.
I would propose this kind of design.
class DateTimeSlug(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
slug = models.CharField(max_length=240)
class Meta:
abstract = True
class NameDesc(models.Model):
name = models.CharField(max_length=256)
desc=models.TextField()
class Meta:
abstract = True
class Story(models.Model):
stry = models.CharField(max_length=256, primary_key=True)
def __str__(self):
return self.stry
class Section(DateTimeSlug, NameDesc):
stry = models.ForeignKey(Story,on_delete=models.CASCADE, related_name='sections')
class Chapter(DateTimeSlug, NameDesc):
sec = models.ForeignKey(Section,on_delete=models.CASCADE, related_name='chapters')
class Paragraph(DateTimeSlug):
chap = models.ForeignKey(Chapter, on_delete=models.CASCADE, related_name='paragraphs')
title = models.CharField(max_length=120)
subtitle = models.CharField(max_length=180)
body = models.TextField()
id = models.AutoField(primary_key=True) is not necessary, because Django adds id with AutoFieldautomatically. If you want to use a custom PrimaryKey, you have to make your own. I propose you can do it at Story.stry. Adding blank=False, null=False is not necessary. It is Django standard behavior.
If you want to use a model in yoru index-App, you can import it where you need it.
Can divide these into different apps or have 1 app for each genre or include genre as a model.
In my opinion, I would add a kind of "genre-tag" at your Story-model and keep it all together.
I'm kind of new to Django and am having some trouble pulling from existing tables. I'm trying to pull data from columns on multiple joined tables. I did find a solution, but it feels a bit like cheating and am wondering if my method below is considered proper or not.
class Sig(models.Model):
sig_id = models.IntegerField(primary_key=True)
parent = models.ForeignKey('self')
state = models.CharField(max_length=2, db_column='state')
release_id = models.SmallIntegerField(choices=releaseChoices)
name = models.CharField(max_length=255)
address = models.CharField(max_length=255, blank=True)
city = models.CharField(max_length=255, blank=True)
zip = models.CharField(max_length=10, blank=True)
phone1 = models.CharField(max_length=255, blank=True)
fax = models.CharField(max_length=255, blank=True)
email = models.EmailField(max_length=255, blank=True)
url = models.URLField(max_length=255, blank=True)
description = models.TextField(blank=True)
contactname = models.CharField(max_length=255, blank=True)
phone2 = models.CharField(max_length=255, blank=True)
ratinggroup = models.BooleanField()
state_id = models.ForeignKey(State, db_column='state_id')
usesigrating = models.BooleanField()
major = models.BooleanField()
class Meta:
db_table = u'sig'
class SigCategory(models.Model):
sig_category_id = models.IntegerField(primary_key=True)
sig = models.ForeignKey(Sig, related_name='sigcategory')
category = models.ForeignKey(Category)
class Meta:
db_table = u'sig_category'
class Category(models.Model):
category_id = models.SmallIntegerField(primary_key=True)
name = models.CharField(max_length=255)
release_id = models.SmallIntegerField()
class Meta:
db_table = u'category'
Then, this was my solution, which works, but doesn't quite feel right:
sigs = Sig.objects.only('sig_id', 'name').extra(
select = {
'category': 'category.name',
},
).filter(
sigcategory__category__category_id = categoryId,
state_id = stateId
).order_by('sigcategory__category__name', 'name')
Now since the items in filter() join the sigcategory and category models, I was able to pull category.name out by using extra(). Is this a proper way of doing this? What if I did not have the reference in filter() and the join did not take place?
SigCategory has a ForeignKey pointing at Category, so you can always get from the SigCategory to the Category simply by doing mysigcategory.category (where mysigcategory is your instance of SigCategory.
If you haven't previously accessed that relationship from that instance, doing it here will cause an extra database lookup - if you're concerned about db efficiency, look into select_related.
I'm trying to do a formset with the following models (boost is the primary):
class boost(models.Model):
creator = models.ForeignKey(userInfo)
game = models.ForeignKey(gameInfo)
name = models.CharField(max_length=200)
desc = models.CharField(max_length=500)
rules = models.CharField(max_length=500)
subscribe = models.IntegerField(default=0)
class userInfo(models.Model):
pic_url= models.URLField(default=0, blank=True)
auth = models.ForeignKey(User, unique=True)
birth = models.DateTimeField(default=0, blank=True)
country= models.IntegerField(default=0, blank=True)
class gameInfo(models.Model):
psn_id = models.CharField(max_length=100)
name = models.CharField(max_length=200)
publisher = models.CharField(max_length=200, default=0)
developer = models.CharField(max_length=200, default=0)
release_date = models.DateTimeField(blank=True, null=True)
I want to display a form to add a Boost item, trying to do in this way :
TrophyFormSet = inlineformset_factory(db.gameInfo, db.boost, extra=1)
formset = TrophyFormSet()
Here are my questions :
1 - When rendered, the combo box for "Creator" shows a list of "db.userInfo" (literally)! I want this to display db.userInfo.auth.username that is already in the database... how to do this?
2 - In this way, where is my "db.gameInfo" to choose?
thank you! =D
======
czarchaic answered my question very well!
But now I need just a little question:
When I use the modelform to create a form for the boost_trophy model :
class boost_trophy(models.Model):
boost = models.ForeignKey(boost)
trophy = models.ForeignKey(gameTrophyInfo)
# 0 - Obtiveis
# 1 - Requisitos minimos
type = models.IntegerField(default=0)
class gameTrophyInfo(models.Model):
game = models.ForeignKey(gameInfo)
name = models.CharField(max_length=500)
desc = models.CharField(max_length=500)
type = models.CharField(max_length=20)
It works nice, but I want the form to show in the "game" box only a really small set of items, only the: gameTrophyInfo(game__name="Game_A") results. How can I do this?
If I understand you correctly:
To change what is displayed set the model's __unicode__ function
class userInfo(models.Model):
#model fields
def __unicode__(self):
return self.auth.username