Django-nonrel on Appengine - django

class BillList(models.Model):
username = models.ForeignKey(User)
billno = models.CharField(max_length=15)
class OrderDetails(models.Model):
billno = models.ForeignKey(BillList)
orderdetails = models.TextField()
User is the one within django.contrib.auth.models.
I need to retreive all billno of a particular user. How do I go about doing this simple query in Django-nonrel on Appengine?
If I do this:
iq = User.objects.filter(username = "name1")
BillList.objects.filter(username = iq)
Then I get an error: DatabaseError: Subqueries are not supported.
If I try this straight away BillList.objects.filter(username = "restaurant1"), then ValueError: invalid literal for long() with base 10: 'restaurant1'
I'm sure it must be possible to go about doing this simple query! Any workarounds?

The others are correct. But, there may be a fundamental problem here with your understanding of the ForeignKey. For example:
username = models.ForeignKey(User)
That's not really a "username" at all. It is a user object. More understandable would be something like:
user = models.ForeignKey(User)
The User object is what has the username property. So to get a person's username, you would use"
BillList.objects.get(billno = 12345).user.username
Then, your queries become:
iq = User.objects.get(username = "name1")
my_list = BillList.objects.all().filter(user = iq)
Or, more directly:
my_list = iq.billist_set.all()

Related

get foreign key related data in django using filter

This is the model :
class Requirement(models.Model):
name = models.CharField(max_length=100)
user = models.ForeignKey(
User,on_delete=models.CASCADE, related_name = 'user'
)
assigned_user = models.ForeignKey(
User,related_name = "assigned",on_delete=models.CASCADE,
)
I am running this query:
requirementsOb = Requirement.objects.filter(user = currentUser)
Where currentUser is logged in user. The result returns multiple requriements. I also want to get all user related data. How can i get user related data only for assigned_user
You can try like this:
current_user = request.user
requirements = current_user.user.all() | current_user.assigned.all()
Or you can try this approach:
requirementsOb = Requirement.objects.filter(Q(user = currentUser) | Q(assigned_user=currentUser))
If you want to get user data from requirements, you can try:
for r in requirementsOb:
r.user
r.assigned_user
If you want to get only the first requirement from the requirementsOb, then try like this:
requirement = requirementsOb.first() # or .last() for last object
requirement.user
requirement.assigned_user
More information can be found in documentation.

Assigning value to foreign key field

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()

Get verbose name of foreign key from objects _meta dynamically in Django

For simplicity sake, with models like the following:
class Plan(models.Model)
name = models.CharField(max_length=255, verbose_name="Phone Plan Name")
monthly_charge = models.FloatField()
class Company(models.Model):
name = models.CharField(max_length=255, verbose_name="Company Full Name")
phone_plan = models.ForeignKey(Plan)
class Client(models.Model):
name = models.CharField(max_length=255, verbose_name="Client Full Name")
company = models.ForeignKey(Company)
Given a string, I want to know if there is an easy way to retrieve the verbose name of a model attribute even if that string traverses through foreign keys.
I know that I can get the verbose name of a Client attribute by
Client._meta.get_field("name").verbose_name
and this would result in "Client Full Name".
But what if I had the string "company__phone_plan__name", I cannot simply use
Client._meta.get_field("company__phone_plan__name").verbose_name
to arrive at "Phone Plan Name" as it yields an error.
These strings will be dynamic, so I am wondering what is the easiest way to arrive at the proper verbose name of an attribute, even if it traverses models?
This particular case is using Django 1.11
This is not so good answer but if you need what you want you can use this function:
def get_verbose_name(model, string):
fields = string.split('__')
for field_name in fields[:-1]:
field = model._meta.get_field(field_name)
if field.many_to_one:
model = field.foreign_related_fields[0].model
elif field.many_to_many or field.one_to_one or field.one_to_many:
model = field.related_model
else:
raise ValueError('incorrect string')
return model._meta.get_field(fields[-1]).verbose_name
This function gets model name and string and return verbose name
You can use it like so:
get_verbose_name(Client, 'company__phone_plan__name')
If you are working with instances of the models, then you could try this:
c = Client.objects.first()
# c._meta.get_field('company').verbose_name
# c.company._meta.get_field('phone_plan').verbose_name
c.company.phone_plan._meta.get_field('name').verbose_name
If you are working with classes only, then its a but more complex:
field_company = Client._meta.get_field('company')
field_phone_plan = field_company.rel.to._meta.get_field('phone_plan')
field_name = field_phone_plan.rel.to._meta.get_field('name')
field_name.verbose_name
# or one long line
s = Client._meta.get_field('company') \
.rel.to._meta.get_field('phone_plan') \
.rel.to._meta.get_field('name') \
.verbose_name
EDIT:
User #AndreyBerenda points out that the second option does not work for him in Django 2.1; I tested only in 1.11, which was specified in the question.

Changes to model with one to one relation not saving

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)

Django get attribtues of foreign key

I have an intermediate model -
class Link_Book_Course(models.Model):
book = models.ForeignKey(Book)
course = models.ForeignKey(Course)
image = models.CharField(max_length = 200, null=True)
rating = models.CharField(max_length = 200,null=True)
def save(self,*args,**kwargs):
self.date_created = datetime.now()
super(Link_Book_Course,self).save(*args,**kwargs)
and I need to get the book name and title (which are attributes of Book) from a specified Link_Book_Course.
This is what I've come up with, but it doesn't work- instances don't have access to the manager apparently -
storedCourse = Link_Book_Course.objects.filter(course__name= nameAndNumberStore[0] + nameAndNumberStore[1])
storedLink = Link_Book_Course.objects.filter(course = storedCourse)[0]
storeOfAuthorNames = storedLink.objects.values('book__author')
storeOfBookNames = storedLink.objects.values('book__title')
EDIT-
Nevermind, I've figured it out- for reference sake- you can't get attributes through a foreign key relationship.
Instead I filtered the Books that had the course that the user searched for.
Here's an even easier way!
>>> course = Course.objects.filter(name= nameAndNumberStore[0] + nameAndNumberStore[1])
>>> links = course.link_book_course_set.all()
>>> BookAuthorNames = [(link.book.title, link.book.author) for link in links]
(('Book1','Author1'),('Book2','Author2'),...)
Remember, the django ORM is powerful!