I'implemented two models, Card and Dish. I used many-to-many relationship because Dish can be in many cards. Not sure if I did that right because any Dish that I add is automatically added to every Card.
Here is the code:
class Dish(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.TextField(max_length=1000)
price = models.DecimalField(max_digits=5, decimal_places=2)
preparation_time = models.IntegerField()
date_added = models.DateField(auto_now_add=True)
update_date = models.DateField(auto_now=True)
vegan = models.BooleanField(default=False)
def __str__(self):
return self.name
class Card(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.TextField(max_length=1000)
date_added = models.DateField(auto_now_add=True)
update_date = models.DateField(auto_now=True)
dishes = models.ManyToManyField(Dish, blank=True)
def __str__(self):
return self.name
An the problem in admin panel looks like this:
When I create a dish it is alway added to every card.
Any help please I'm just begining to learn sql and django ORM
Dishes being in that admin field doesn't mean they're actually selected, that's just the Multi-Select field. Only the ones that are highlighted are actually in the field. and you do +Click to toggle if they're selected or not
I guess that was the best way to show a Many-to-Many field, tho it might be confusing to use imo.. That's why I always just edit them in the shell, especially when there gets 100+, 200+ items.
Related
I'm creating a small-ish django application using AllAuth for the authetncation, which I have customised myself to include some additional fields.
Part of the sites functionality requires me to refrence the logged in user through a Foreign Key multiple times and I'm approaching this through the custom model I created, called UserProfile; (I tried Django's User model & this also gave me errors)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
phone_number = models.CharField(max_length=30, null=False)
postcode = models.CharField(max_length=500, null=True, blank=True)
town_or_city = models.CharField(max_length=40, null=True, blank=True)
street_address1 = models.CharField(max_length=80, null=True, blank=True)
street_address2 = models.CharField(max_length=80, null=True, blank=True)
county = models.CharField(max_length=80, null=True)
I'm referencing the above model in the activity table:
class Activity(models.Model):
class Meta:
verbose_name_plural = 'Activities'
activity_id = models.CharField(max_length=32, null=False, editable=False)
host = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
name = models.CharField(max_length=254, null=False, blank=False)
date = models.DateField()
start_time =models.TimeField()
end_time = models.TimeField()
duration = models.DurationField(blank=True, null=True)
location = models.CharField(max_length=40, null=False, blank=False)
description = models.CharField(max_length=140, null=False, blank=False)
available = models.BooleanField(default=True)
Everything works smoothly, as I can use this to create one activity per user, however I want to make this a Many to One field, which required me to update from settings.AUTH_USER_MODEL to the Foreign Key.
Unfortunately, I'm getting the following error:
FOREIGN KEY constraint failed
when I try to add a new activity now, and I'm at a loss as to why this is happening.
If someone could point me in the right direction on how to create this many to one functionality, it would be great.
I can't see your whole code so the answear may be wrong but it Looks like you dont have Primary Key in UserProfile
ForeignKey As Default takes Primary Key as argument
Potential solve:
class Activity(models.Model):
host = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile', primary_key=True)
If it dosent solve your problem please put full error message
DOCS
I would guess, from what information that you've provided, is that what has happened is that you've potentially got a user who doesn't have a user profile, so when you try to create the activity it fails with the error you specified. On the other hand, it could also be related to how you're rendering and validating your forms. Furthermore it could also be due to the way you are using class based views views or function based views.
In any case, please provide all information possible. Generally all information is required, not just the part you're unsure of.
How do you create an activity?
How do you validate your forms?
How is the user profile ID populated?
Providing more information, I will happily respond as it seems like a straight forward question
I have the following models Program, Course, ProgramAdmission, CourseEnrollment.
Each course is associated with a program.
During program admission, I am showing the list of available courses for the selected program. For each shown course, I want to show a dropdown menu with the following selections: Not Planned and Planned.
Now if the user saves the new program admission, I want also to enroll the user in the planned courses by creating CourseEnrollment in the server-side for each planned course.
And if the user discards the new program admission, nothing should be created in the database.
How can I allow for such conditional batch creation of model objects?
Thank you!
It's easy, you just need to start to coding it. Create the module with the models relations and fields. On the ProgramAdmission model add a Many2one field to the Program model and another to the Course model. If you cancel the form while creating a new record nothing will be saved in your DB, but if you hit the Save button it will call the create method for new records and write methods for existing ones. Override the create method to be able to dynamically create a new record of the CourseEnrollment model and associate it with the ProgramAdmission record to be created by saving it to a new Many2one field in the same ProgramAdmission model.
To make what I mean more clear:
from odoo import models, fields, api
class Program(models.Model):
_name = 'school.program'
name = fields.Char()
class Course(models.Model):
_name = 'school.course'
name = fields.Char()
class ProgramAdmission(models.Model):
_name = 'school.program.admission'
course_id = fields.Many2one('school.course')
program_id = fields.Many2one('school.program')
enrollment_id = fields.Many2one('school.course.enrollment')
#api.model
def create(self, vals):
enrollment_id = self.env['school.course.enrollment'].create({
'course_id': vals['course_id'],
'program_id': vals['program_id']
})
vals['enrollment_id'] = enrollment_id.id
return super(ProgramAdmission, self).create(vals)
class CourseEnrollment(models.Model):
_name = 'school.course.enrollment'
course_id = fields.Many2one('school.course')
program_id = fields.Many2one('school.program')
I have Picture model which contains different link to images. I also have People and Car models that may have one or more images. That means that certain pictures can belong to an object in Car or People model.
I try to make ForeignKey but one of the field (car_id or people_id) will be empty.
I can't create an abstract model and make ForeignKey from Picture
The last solution that I know is genericForeignKey but it seems to complex for such trivial task.
Is there are a best way to solve the problem?
I solved the problem like this:
I created another model called Album that has only id
class People(models.Model):
name = models.CharField(max_length=100)
album = models.OneToOneField(Album)
class Car(models.Model):
horse_power = models.IntegerField()
ablum = models.OneToOneField(Album)
class Picture(models.Model):
title = models.CharField(max_length=100)
album = models.ForeignKey(Album)
Pretty new to working with databases in this way. I've got some sample code below. I've got the instrument object which will be a db listing of types of instruments, guitar, piano etc. Then the user object will have a ManyToMany on that so each user can have as many of those listed in their profile as they play.
What I'm stuck on is I'd like to have a field for experience with each of those instruments. Just not sure how to accomplish this without just static fields for how many instruments there would be (which since it's modifiable, could change). Thanks for any pointing in the correct direction.
class Instrument(models.Model):
# Name of the instrument
name = models.CharField(_('Name of Instrument'), blank=True, max_length=255)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
#python_2_unicode_compatible
class User(AbstractUser):
# First Name and Last Name do not cover name patterns
# around the globe.
name = models.CharField(_('Name of User'), blank=True, max_length=255)
zipcode = models.IntegerField(_('Zip Code of the User'), blank=True, null=True)
instruments = models.ManyToManyField(Instrument)
Seems like a textbook use case for a through model with extra fields.
class InstrumentExperience(models.Model):
user = models.ForeignKey('User')
instrument = models.ForeignKey('Instrument')
experience = models.CharField(max_length=100)
class User(AbstractUser):
...
instruments = models.ManyToManyField('Instrument', through='InstrumentExperience')
I have two indirectly related tables - Posts and Follower_to_followee
models.py:
class Post(models.Model):
auth_user = models.ForeignKey(User, null=True, blank=True, verbose_name='Author', help_text="Author")
title = models.CharField(blank=True, max_length=255, help_text="Post Title")
post_content = models.TextField (help_text="Post Content")
class Follower_to_followee(models.Model):
follower = models.ForeignKey(User, related_name='user_followers', null=True, blank=True, help_text="Follower")
followee = models.ForeignKey(User, related_name='user_followees', null=True, blank=True, help_text="Followee")
The folowee is indirectly related to post auth_user (post author) in posts. It is, though, directly related to Django user table and user table is directly related to post table.
How can I select all followees for a specific follower and include post counts for each followee in the result of the query without involving the user table? Actually, at this point I am not even clear how to do that involving the user table. Please help.
It's possible to write query generating single SQL, try something like
qs = User.objects.filter(user_followees__follower=specific_follower).annotate(
post_count=models.Count('post'))
for u in qs:
print u, u.post_count
Check the second part of https://stackoverflow.com/a/13293460/165603 (things work similarly except the extra M2M manager)
When being used inside User.objects.filter, both user_followees__follower=foo and user_followers__followee=foo would cause joining of the table of the Follower_to_followee model and a where condition checking for follower=foo or followee=foo
(Note that user_followees__followee=foo or user_followerers__follower=foo works differently from above, Django ORM simplifies them smartly and would generate something like User.objects.filter(pk=foo.pk)).
I'm not entirely sure I understand the question, but here is a simple solution. Note that this could be written more succinctly, but I broke it up so you can see each step.
How can I select all followees for a specific follower?
# First grab all the follower_to_followee entries for a given
# follower called: the_follower
follows = Follower_to_followee.objects.filter(follower=the_follower)
followee_counts = []
# Next, let's iterate through those objects and pick out
# the followees and their posts
for follow in follows:
followee = follow.followee
# post for each followee
followee_posts = Post.objects.filter(auth_user=followee).count()
# Count number of posts in the queryset
count = followee_posts.count()
# Add followee/post_counts to our list of followee_counts
followee_counts.append((followee, count))
# followee_counts is now a list of followee/post_count tuples
For get post counts you can use this:
#get follower
follower = User.objects.get(username='username_of_fallower')
#get all followees for a specific follower
for element in Follower_to_followee.objects.filter(follower=follower):
element.followee.post_set.all().count()
views.py
def view_name(request):
followers = Follower_to_followee.objects.filter(user=request.user)
.......
html
{{user}}<br/>
My followers:<br/>
{% follower in followers %}
<p>{{follower}} - {{follower.user.follower_to_followee_set.count}}</p>
{% endfor %}