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
Related
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.
I want create a table with two primary_key by it's django model as below:
class UserView(Model):
email= columns.Text(primary_key=True)
entryLink= columns.Text(primary_key=True)
date= columns.Date(default=datetime.date.today())
but when I want create table as below:
>>> from cqlengine import connection
>>> from cqlengine.management import create_table
>>> from MainAPP.models import UserView
>>> connection.setup(['127.0.0.1:9160'])
>>> create_table(UserView)
I see this error:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "H:\Web-Programming\Python\Project\Prexter\Virtual-Environment\Lib\site-packages\cqlengine\management.py", line 97, in create_table
execute(qs)
File "H:\Web-Programming\Python\Project\Prexter\Virtual-Environment\Lib\site-packages\cqlengine\connection.py", line 172, in execute
return connection_pool.execute(query, params)
File "H:\Web-Programming\Python\Project\Prexter\Virtual-Environment\Lib\site-packages\cqlengine\connection.py", line 164, in execute
raise CQLEngineException(unicode(ex))
CQLEngineException: Bad Request: Missing CLUSTERING ORDER for column entryLink
When I remove primary_key property from entryLink field, I have no error! but I want define entryLink as a primary_key! What is my mistake?
A database table cannot have 2 primary key. If you are looking for a Composite Primary Key, Django does not support that yet.
Now, what you might be looking for is unique=True (a candidate key).
class UserView(Model):
email= columns.Text(primary_key=True)
entryLink= columns.Text(unique=True)
date= columns.Date(default=datetime.date.today())
You can also read this post for a better understanding
I found My Answer! This is a funny bug!
I have a capitalized character among entryLink field, and it caused considered error! This is so funny! because this applies to primary_key only! and it isn't true about other fields!!! primary_keys can't have a capitalized character among!
My modified code:
class UserView(Model):
email= columns.Text(primary_key=True)
link= columns.Text(primary_key = True)
date= columns.Date(default=datetime.date.today())
The following code works as I expect it to:
class General(Model):
pass
class Captain(Model):
general = ForeignKey('General',related_name='captains')
I can create a general, add captains, and doing "general.captains" works as expected.
But when both these classes inherit from a base class that might have extra info, disaster strikes.
class Officer(Model):
pass
class General(Officer):
pass
class Captain(Officer):
general = ForeignKey('General',related_name='captains')
>>> g = General()
>>> g.captains
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python27\lib\site-packages\django\db\models\fields\related.py", line
391, in __get__
self.related.model._default_manager.__class__)
File "C:\Python27\lib\site-packages\django\db\models\fields\related.py", line
469, in create_manager
getattr(instance, attname)}
File "C:\Python27\lib\site-packages\django\db\models\fields\related.py", line
301, in __get__
raise self.field.rel.to.DoesNotExist
DoesNotExist
Any idea what might be happening here, and how I could fix it?
It should work if you define your Officer model explicitly as abstract
class Meta:
abstract = True
So as a test i slightly modified your base class:
class Officer(models.Model):
name = models.CharField(max_length=255)
class Meta:
abstract = True
And the following works:
>>> General(name='Warfield').save()
>>> G = General.objects.all()[0]
>>> Captain(name='Picard', general=G).save()
>>> C = Captain.objects.all()[0]
>>> C.general.name
u'Warfield'
>>> G.captains.all()[0].name
u'Picard'
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.
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.