I have two models that I'm relating using Django's OneToOneField, following this documentation: https://docs.djangoproject.com/en/2.0/topics/db/examples/one_to_one/
class Seats(models.Model):
north = models.OneToOneField('User',on_delete=models.CASCADE,related_name='north', default=None, null=True)
bridgetable = models.OneToOneField('BridgeTable',on_delete=models.CASCADE, default=None, null=True)
class BridgeTableManager(models.Manager):
def create_deal(self):
deal = construct_deal()
table = self.create(deal=deal)
s = Seats(bridgetable=table)
s.save()
return table
class BridgeTable(models.Model):
deal = DealField(default=None,null=True)
When I run this code I can successfully get the relationship working
table = BridgeTable.objects.get(pk='1')
user = User.objects.get(username=username)
table.seats.north = user
table.seats.north.save()
print(table.seats.north)
The print statement prints out the name of the player sitting north. But if I try to access the table again like this:
table = BridgeTable.objects.get(pk='1')
print(table.seats.north)
I get "None" instead of the user's name. Is there something I'm missing, like a save that I missed or some concept I'm not understanding? Thanks.
You should save Seats model object that is table.seats.save()
Try print table.seats.north
While table.seats.north.save() runs save on User object
Here are correct steps:
table = BridgeTable.objects.get(pk='1')
user = User.objects.get(username=username)
table.seats.north = user
table.seats.save()
print(table.seats.north)
Related
I want to filter Employee, only those that have a ForeignKey, how to do it? My solution does not returned any results.
Models.py
class Employee(models.Model):
name = models.CharField(max_length=200)
class ExperienceCategory(models.Model):
name = models.CharField(max_length=100, unique=True)
class Experience(models.Model):
user = models.ForeignKey(Employee, on_delete=models.CASCADE)
category = models.ForeignKey(ExperienceCategory, on_delete=models.CASCADE)
Views.py
experience_category = *ExperienceCategory object (1)*
#solution - final query
employee_query = Employee.objects.filter(experience__category = experience_category)
How to get employees who have a foreign key from Experience?
What you have should work just fine, as an example to reproduce that
first_employee = Employee.objects.create(name='First')
second_employee = Employee.objects.create(name='Second')
experience_category = ExperienceCategory.objects.create(name='sample_category')
Experience.objects.create(user=first_employee, category=experience_category)
Experience.objects.create(user=second_employee, category=experience_category)
employee_query = Employee.objects.filter(experience__category = experience_category)
employee_query
>>> <QuerySet [<Employee: Employee object (1)>, <Employee: Employee object (2)>]>
If you get an empty queryset it's because either there is no Experience instance with related category equal to experience_category in your database. To get the count of how many Experience instances matching this filter exist in your database you can run
Experience.objects.filter(category=experience_category).count()
In the case I provided it would return 2. Check first that this method returns a number greater than 0. If it returns 0 you should create some Experience instances first with the corresponding category.
I'm having difficulty assigning a title to the UserService model, which is a foreign key to another model.
models.py
class IndustryService(models.Model):
industryname = models.ForeignKey(Industry, on_delete=models.CASCADE)
title = models.CharField(max_length=120)
class UserService(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
title = models.ForeignKey(IndustryService, on_delete=models.CASCADE)
Here is the portion of code within the view that is failing:
industryservices = IndustryService.objects.filter(industryname=industry)
for service in industryservices:
try:
qs = UserService.objects.get(user=user, title=service.title)
except:
userserv = UserService.objects.create(user=request.user)
userserv.title = service
userserv.save()
The error that I'm getting is as follows:
NOT NULL constraint failed: accounts_userservice.title_id
Based on my testing, the way in which I'm assigning the value to the 'title' foreign key field is wrong (i.e. these 2 lines of code).
service2 = IndustryService.objects.get(title=service.title)
userserv.title = service2
Any thoughts on how I can fix this? Thanks!
You're doing two updates, unnecessarily. Either create the item in one go:
userserv = UserService.objects.create(user=request.user, title=service)
or instantiate without saving and then save at the end:
userserv = UserService(user=request.user)
userserv.title = service
userserv.save()
I have a History model like below
class History(models.Model):
class Meta:
app_label = 'subscription'
ordering = ['-start_datetime']
subscription = models.ForeignKey(Subscription, related_name='history')
FREE = 'free'
Premium = 'premium'
SUBSCRIPTION_TYPE_CHOICES = ((FREE, 'Free'), (Premium, 'Premium'),)
name = models.CharField(max_length=32, choices=SUBSCRIPTION_TYPE_CHOICES, default=FREE)
start_datetime = models.DateTimeField(db_index=True)
end_datetime = models.DateTimeField(db_index=True, blank=True, null=True)
cancelled_datetime = models.DateTimeField(blank=True, null=True)
Now i have a queryset filtering like below
users = get_user_model().objects.all()
queryset = users.exclude(subscription__history__end_datetime__lt=timezone.now())
The issue is that in the exclude above it is checking end_datetime for all the rows for a particular history object. But i only want to compare it with first row of history object.
Below is how a particular history object looks like. So i want to write a queryset filter which can do datetime comparison on first row only.
You could use a Model Manager method for this. The documentation isn't all that descriptive, but you could do something along the lines of:
class SubscriptionManager(models.Manager):
def my_filter(self):
# You'd want to make this a smaller query most likely
subscriptions = Subscription.objects.all()
results = []
for subscription in subscriptions:
sub_history = subscription.history_set.first()
if sub_history.end_datetime > timezone.now:
results.append(subscription)
return results
class History(models.Model):
subscription = models.ForeignKey(Subscription)
end_datetime = models.DateTimeField(db_index=True, blank=True, null=True)
objects = SubscriptionManager()
Then: queryset = Subscription.objects().my_filter()
Not a copy-pastable answer, but shows the use of Managers. Given the specificity of what you're looking for, I don't think there's a way to get it just via the plain filter() and exclude().
Without knowing what your end goal here is, it's hard to say whether this is feasible, but have you considered adding a property to the subscription model that indicates whatever you're looking for? For example, if you're trying to get everyone who has a subscription that's ending:
class Subscription(models.Model):
#property
def ending(self):
if self.end_datetime > timezone.now:
return True
else:
return False
Then in your code: queryset = users.filter(subscription_ending=True)
I have tried django's all king of expressions(aggregate, query, conditional) but was unable to solve the problem so i went with RawSQL and it solved the problem.
I have used the below SQL to select the first row and then compare the end_datetime
SELECT (end_datetime > %s OR end_datetime IS NULL) AS result
FROM subscription_history
ORDER BY start_datetime DESC
LIMIT 1;
I will select my answer as accepted if not found a solution with queryset filter chaining in next 2 days.
I keep getting these inner join errors when I try to delete an object. It's a programming error, and an exception value of "column main_reviewerauthoranswer.screener_id does not exist
LINE 1: ...viewerauthoranswer" INNER JOIN "main_reader" ON ( "main_revi..."
I'm using south. I'm migrating just fine. Creating instances just fine. But if I try to delete something I keep getting those errors. I don't know if something changed in django 1.6 with through tables? I'm very confused.
So this is what I"m doing. Empty database. I create a reader in the admin, I give the reader a genre ( I create it in the admin). Save. No problem. Ok, try to delete the reader I get
column main_reviewerauthoranswer.screener_id does not exist
LINE 1: ...viewerauthoranswer" INNER JOIN "main_reader" ON ( "main_revi...
If i try to delete the genre I just created for that reader I get a
column main_reviewerauthoranswer.screener_id does not exist
LINE 1: ...viewerauthoranswer" INNER JOIN "main_reader" ON ( "main_revi...
So obviously there is something wrong with my ReviewAuthorAnswer model. But I dont' see what
My models looks like this:
class DateDocumentation(models.Model):
modified_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
abstract = True
class Author(DateDocumentation):
user = models.OneToOneField(User, null=True)
class Reader(DateDocumentation):
user = models.OneToOneField(User)
favorite_genre = models.ForeignKey('Genre')
class Genre(models.Model):
title = models.CharField(max_length=100
class Book(DateDocumentation):
author = models.ForeignKey('Author')
book = models.FileField(upload_to='books/')
genre = models.ForeinKey('Gengre')
class Blurbreview(DateDocumentation):
reader = models.ForeignKey("Reader")
review = models.ForeignKey("Review")
class Review(DateDocumentation):
book = models.ForeignKey('Book')
blurb_readers = models.ManyToManyField("Reader",
through="blurbreview",
related_name='blurb_readers')
readers = models.ManyToManyField("Reader",
help_text="Readers that downloaded this book",)
class BaseQuestion(DateDocumentation):
review = models.ForeignKey("Review")
reviewer = models.ForeignKey("Reader")
class AuthorQuestion(DateDocumentation):
review = models.ForeignKey('Review')
class ReviewerAuthorAnswer(DateDocumentation):
question = models.ForeignKey('AuthorQuestion')
screener = models.ForeignKey('Reader')
You may have to rebuild the database. When you import new data, make sure that you run foreign_key_check=0; before the query.
I ran into this issue several times when I mistakenly tried importing data into an emptied database.
I need to get a list of users who have been referenced as a ForeignKey in two other models. I'm still a little unclear on queries when they reach this complexity.
Models:
class Page(models.Model):
user = models.ForeignKey(User)
class EmailSent(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=200)
In English, what I want to get is: 10 active users who have 0 pages and have never had an email with the name check_in sent to them.
Here's where I am:
users = User.objects.filter(is_active=1).annotate(page_count=Count('pages')).filter(page_count=0)[10]
but not sure how to do what is essentially:
email_sent = EmailSent.objects.filter(user=user, name='check_in')
Any ideas?
One possible way to get what you want is:
users = User.objects.filter(is_active=1).annotate(page_count=Count('pages')).filter(page_count=0)
EmailSent.objects.filter(user__in=users, name='check_in')[10]
Another way is,
users = User.objects.filter(is_active=1).annotate(page_count=Count('pages')).filter(page_count=0)
users.emailsent_set.all()[10]
Try the following:
users = User.objects.filter(is_active=1)\
.exclude(emailsent__name='check_in')\
.extra(select={'page_count': "select count(*) from YOURAPP_page where user_id = auth_user.id"}, where=['page_count 0'])[:10]