Comments and content_object - django

I'm trying to figure out why this works:
>>> comments = Comment.objects.all()
>>>[c.content_object for c in comments]
[returns a list of the objects the comments are attached to]
But this doesn't:
>>> c = Comment.objects.filter(id=111)
>>> c
[<Comment: Related object name here ...>]
>>> c.content_object
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'QuerySet' object has no attribute 'content_object'
In both cases, each "c" is a Comment instance. So why does c have a content_object property in the first case but not in the second? Thanks.

No, in both cases you get a queryset. In the first one, you iterate through and get the content_object for every item in the queryset - but in the second one, you try and call it on the entire queryset, for some reason. If you iterated through the second one in the same way as you do the first, it would work.
Alternatively, and this is probably what you actually wanted to do, you could use:
c = Comment.objects.get(id=111)
to get the actual Comment object with ID 111, rather than a queryset consisting of one element.

Related

Django Model instance with variable

This is the only way I can get the value I need:
User1.types1.r_q2.label
I want to make it dynamic by replacing field name and textChoices with variable. How can I get it done?
Models.py:
class User1(models.Model):
class r_q1(models.TextChoices):
r_q2 = 'r_q2', 'second question'
r_q3 = 'r_q3', 'third question'
t_greeting = 't_greeting', 't_greeting'
f_passport = 'f_passport', 'Contact with a human f_passport'
r_q1 = models.CharField (
'How can I help you, today?1',
max_length=200,
choices=r_q1.choices, blank=True, null=False
)
This works but when I replace only fieldname:
User1.types1[x].label
When I do it for textChoices name it doesn't work and raise error:
User1[y][x].label
error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'ModelBase' object is not subscriptable
Sidenote: I have many textChoices in my models.py. I didn't include them as they are not important here.
I get it to work by using getattr().
getattr(User1, 'types1')['r_q2'].label
When using variables:
y='types1'
x='r_q2'
getattr(User1, y)[x].label
There won't be any problem.

Counting mongoengine ListField elements

I`m having a hard time migrating my models from standard Django orm with MySQL to mongoengine-odm.
I have the following model that works fine in the old structure:
class Place(Document):
name = StringField()
acronym = StringField()
parent = ReferenceField('self')
hierarchy = ListField(ReferenceField('self'))
hierarchy_size = IntField()
#classmethod
def preSave(instance, sender, **kwargs):
instance.hierarchy_size = len(instance.hierarchy)
signals.pre_save.connect(Place.preSave, sender=Place)
But when working with the new mongoengine, I'm facing problems to access the objects hierarchy size in the way I was doing before. Receiving:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/awesome_user/workspace/awesome_project/project/models.py", line 728, in importPlacesFromMySQL
myCountry.save()
File "/Users/awesome_user/workspace/awesome_project/site_env/lib/python2.7/site-packages/mongoengine/document.py", line 220, in save
signals.pre_save.send(self.__class__, document=self)
File "/Users/awesome_user/workspace/awesome_project/site_env/lib/python2.7/site-packages/blinker/base.py", line 267, in send
for receiver in self.receivers_for(sender)]
File "/Users/awesome_user/workspace/awesome_project/project/models.py", line 804, in preSave
instance.hierarchy_size = len(instance.hierarchy)
TypeError: object of type 'ListField' has no len()
Does anyone know how to access the properties of the instance, like the length in my case?
You have a mistake in defining preSave classmethod. You are trying to take a len from hierarchy ListField from Place class (not instance). This is because you are using the first argument of the method - it's not an instance, it's a class itself. Use the 3rd argument instead:
#classmethod
def preSave(cls, sender, document, **kwargs):
document.hierarchy_size = len(document.hierarchy)
len(object.field) will retrieve all child documents and then count. If you only want the length of the array without retrieving all the documents you can use len(object.to_mongo()["field"])

Django get method is yielding an error

I'm following a Django book (Django 1.0 Web Site Development). I'm finding that the book, although straight forward and easy to read, leaves out small details. However, this error that I'm getting, I have not been able to find a solution online. Thanks for any help.
Below, I added the Tag class to my models.py file.
from django.db import models
from django.contrib.auth.models import User
class Link(models.Model):
url = models.URLField(unique=True)
class Bookmark(models.Model):
title = models.CharField(max_length=200)
user = models.ForeignKey(User)
link = models.ForeignKey(Link)
class Tag(models.Model):
name = models.CharField(max_length=64, unique=True)
bookmarks = models.ManyToManyField(Bookmark)
Then I attempt to run the following code at the python shell:
from bookmarks.models.import *
bookmark = Bookmark.objects.get(id=1)
As a result, I get the following error:
Traceback (most recent call last):
File "(console)", line 1, in (module)
File "c:\Python27\lib\site\-packages\django\db\models\manager.py", line 132, in get
return self.get_query_set().get(*args, **kwargs)
File "c:\Python27\lib\site-packages\django\db\models\query.py", line 349, in get
% self.model._meta.object_name)
DoesNotExist: Bookmark matching query does not exist.
The error means just what it says. DoesNotExist is raised by QuerySet.get() if there is no object in the database that would match the conditions given to the QuerySet. In this case it means there is no Bookmark object in the database with an ID equal to 1.
Did you add any data in the Bookmark table yet? DoesNotExist is raised by get if there is no record corresponding to your query. i.e. if there is no record corresponding to id=1.

django add_to_class() making models inheritance/MRO work wrong

I have a problem with inheritance on my models when adding fields via add_to_class().
I have a models File(models.Model) and Image(File) - these come from django-filer.
In my app I'm importing them and adding fields and methods:
def method_x(self):
print "x"
File.add_to_class("expiration_date", models.DateField(null=True, blank=True))
File.add_to_class("method_x", method_x)
Image should inherit both of those but it gets only the method(s), not field(s):
>>> some_file = File.objects.get(id=8)
>>> some_image = Image.objects.get(id=8)
>>>
>>> print some_file.expiration_date # this works
... None
>>>
>>> some_image.metgod_x() # this works
>>> x
>>>
>>> print some_image.expiration_date # and this not
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Image' object has no attribute 'expiration_date'
Any clue?
Your model's add_to_class does not add the field as an attribute. it just calls contribute_to_class on your field:
django/db/models/base.py#L218
Your field's contribute_to_class does not do it either. It just adds the field to the model's _meta member: django/db/models/fields/__init__.py#L234

In Django, how do you retrieve a field of a many-to-many related class?

I have two classes with a ManyToMany relationship. I'd like to select one from the first class and access the fields of the related class. It seems like this should be easy. For example:
class Topping(models.Model):
name = models.CharField(max_length=40)
class Pizza(models.Model):
name = models.CharField(max_length=40)
toppings = models.ManyToManyField(Topping)
So I'd want to do something like:
Pizza.objects.filter(name = 'Pizza 1')[0].toppings[0]
But this doesn't work for me. Thanks for any help.
Try:
Pizza.objects.filter(name = 'Pizza 1')[0].toppings.all()[0]
It works for me (different models, but the idea is the same):
>>> Affiliate.objects.filter(first_name = 'Paolo')[0]
<Affiliate: Paolo Bergantino>
>>> Affiliate.objects.filter(first_name = 'Paolo')[0].clients
<django.db.models.fields.related.ManyRelatedManager object at 0x015F9770>
>>> Affiliate.objects.filter(first_name = 'Paolo')[0].clients[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'ManyRelatedManager' object is unindexable
>>> Affiliate.objects.filter(first_name = 'Paolo')[0].clients.all()
[<Client: Bergantino, Amanda>]
>>> Affiliate.objects.filter(first_name = 'Paolo')[0].clients.all()[0]
<Client: Bergantino, Amanda>
For more on why this works, check out the documentation.