I create models for MySQL the foreign key
constraints always returning error
The model is
class AirPort(models.Model):
code = models.CharField(max_length=3)
city = models.CharField(max_length=100)
def __str__(self):
return f"{self.id} - CODE =>{self.code} :: CITY=> {self.city}"
class Flight(models.Model):
orgin_id = models.ForeignKey(AirPort,on_delete=models.CASCADE,related_name="dep")
dest_id = models.ForeignKey(AirPort,on_delete=models.CASCADE,related_name="arrival")
duration = models.IntegerField()
def __str__(self):
return f"{self.id} - {self.orgin} TO {self.dest} will take {self.duration} minutes"
and the shell output is
a=Flight(orgin_id=1,dest_id=2,duration=120)
Traceback (most recent call last):
File "", line 1, in
File "/home/kid/PycharmProjects/hardward/venv/lib/python3.6/site-packages/django/db/models/base.py", line 467, in init
_setattr(self, field.name, rel_obj)
File "/home/kid/PycharmProjects/hardward/venv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 210, in set
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "1": "Flight.orgin_id" must be a "AirPort" instance.
Try
a=Flight(orgin=AirPort.object.get(id=1),dest=AirPort.object.get(id=2),duration=120)
You may try this
flight_result=Flight()
flight_result.orgin_id = AirPort.object.first()
flight_result.dest_id = AirPort.object.last()
flight_result.duration = 1000
flight_result.save()
Have you run python manage.py makemigrations...and migrated the data with python manage.py migrate
I received this error because I did not see the comma at the end
order.employee=Employee.objects.get(employee_id=x),
Its origin was that I used Order.objects.create() before, for which one uses comma separated attribute assignments and I did not immediately delete the commas. May it help someone who also sat too long in front of the computer :)
Related
I'm on a project using django and I wrote my models.py
I have two classes
class Adresse(models.Model):
numV=models.IntegerField(blank=False,null=False)
complementdest=models.TextField(blank=False,null=False)
complementadr=models.TextField(blank=False,null=False)
commune=models.TextField(blank=False,null=False)
codeP=models.IntegerField(blank=False,null=False)
pays=models.TextField(blank=False,null=False)
def __str__(self):
return self.numV
return self.complementdest
return self.complementadr
return self.commune
return self.codeP
return self.pays
def __Adr__(self):
return self.adr1.all()
and
class CompteCandidat(myUser):
sexe = models.TextField(max_length=10)
datecr = models.DateTimeField(auto_now_add = True)
adresse=models.OneToOneField('Adresse',related_name='adr1',null=True, default=None)
def __str__(self):
return self.first_name
return self.last_name
return self.email
return self.sexe
def __Adr__(self):
return self.adresse.all()
I try to do some tests like this:
adresse=Adresse(numV='254',complementdest='xxxxx',complementadr='Eugene napoleon',commune='Paris',codeP='75012',pays='France')
c1=CompteCandidat(username='Luna',first_name='celia',last_name='durand',password='CCC',email='hello2#gmail.com',type='candidat',adresse=adresse)
adresse.save()
c1.save()
and when I try to see what I have in my Adresse or in my CompteCandidat by using this command it didn't work
>>> Adresse.__getattribute__(numV)
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'numV' is not defined
i want to know what i'm suppose to do to display what I have in Adresse and CompteCandidat in order to be sure that the add works
i know i Can do :
>>> adresse.numV
'254'
but it works only in the console there is an another way to consult all the database without using the name of the temporery variables ????
You can use
Adresse.objects.all()
to see all records or Adresse.object.filter(numV='254)
to see records satisfying this condition.
For full reference please check:
https://docs.djangoproject.com/ja/1.9/topics/db/queries/
At first in the console try this:
>>>A = {numV='254',complementdest='xxxxx',complementadr='Eugene napoleon',commune='Paris',codeP='75012',pays='France'}
>>> adresse = Adresse(**A)
>>> adresse.save()
At first you will face an error beacuse your numV is Integer but you are assigning an String to it, so should edit numV = '254' to numV = 254 at first line.
Then try above steps again and post that in which step face error.
Two things :
__str__ must only return a single string - as it stands your code tries to return multiple non string values.
the __getattribute__ method (and it's counterpart getattr) should be passed the name of the attribute i.e. a string. Also you shouldn't be trying to call __getattribute__ directly except in exceptional circumstances: ie. you have some form of circular access confilct - which you don't here.
There is no reason that adresse.numV shouldn't work directly in your code - that is the normal way to retrieve attributes from an instance. You should only use getattr if you have the attribute name in a string from elsewhere.
At the risk of sounding rude - if you are struggling to write code that correctly accesses attributes then maybe trying to write a Django App is a case of trying to run before you walk.
I have a document with an array of subdocuments.
These are what the document and the subdocument look like:
class Activity_Comment(EmbeddedDocument):
author_name = StringField()
text_excerpt = StringField()
url = StringField()
class Author_Activity(Document):
author_id = StringField(required=True,primary_key=True)
author_name = StringField()
author_bio = StringField()
latest_comments = ListField(EmbeddedDocumentField(Activity_Comment))
There could be multiple server processes that could modify the the document at the same time.
So I want to use update_one method with upsert=True.
I also want to restrict the number of subdocuments in the array to 5.
It seems this is possible in MongoDB according to these links:
http://docs.mongodb.org/manual/tutorial/limit-number-of-elements-in-updated-array/
http://docs.mongodb.org/manual/reference/operator/update/slice/
These links suggest that I should use $push to insert the subdocuments into the array and $slice to limit the array length to the desired value.
However, I haven't been able to figure out how to do this using MongoEngine. I tried the following code
Author_Activity.objects(author_id="1").update_one(push__latest_comments=activity_comment,slice__latest_comments=5, upsert=True)
but it threw the following exception:
Traceback (most recent call last): File "", line 1, in
File
"/newsoftheworld/local/lib/python2.7/site-packages/mongoengine/queryset/base.py",
line 467, in update_one
upsert=upsert, multi=False, write_concern=write_concern, **update) File
"/newsoftheworld/local/lib/python2.7/site-packages/mongoengine/queryset/base.py",
line 430, in update
update = transform.update(queryset._document, **update) File "/newsoftheworld/local/lib/python2.7/site-packages/mongoengine/queryset/transform.py",
line 181, in update
raise InvalidQueryError(e) InvalidQueryError: Cannot resolve field "slice"
What about findAndModify with returted new value?
If you reached the limit - remove one.
I'm working on in the terminal on a shell script following this tutorial http://docs.sqlalchemy.org/en/latest/orm/tutorial.html SQLAlchemy tutorial on Declare A Mapping. I needed to type in
>>> from sqlalchemy import Column, Integer, String
>>> class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)
def __repr__(self):
return "<\User(name='%s', fullname='%s', password='%s')>" % (
self.name, self.fullname, self.password)
Issue is after I typed the password = Column(String) I hit enter twice and the .... changed to >>>. I then retyped everything back in but then an error was thrown because the class already exists... I'm not totally sure how to fix this. How do I open up that class in the shell script and edit it (add in the def repr)
The error thrown is below:
/Users/GaryPeters/TFsqlAlc001/lib/python2.7/site-packages/sqlalchemy/ext/declarative/clsregistry.py:160: SAWarning: This declarative base already contains a class with the same class name and module name as __main__.User, and will be replaced in the string-lookup table.
existing.add_item(cls)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/GaryPeters/TFsqlAlc001/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", line 53, in __init__
_as_declarative(cls, classname, cls.__dict__)
File "/Users/GaryPeters/TFsqlAlc001/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 251, in _as_declarative
**table_kw)
File "/Users/GaryPeters/TFsqlAlc001/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 339, in __new__
"existing Table object." % key)
sqlalchemy.exc.InvalidRequestError: Table 'users' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
Just close and reopen the shell, and type everything in again, this time making sure to hit enter only once, not twice.
Alternatively, make sure to add the indents whenever you encounter a blank line -- if you hit enter and then hit tab or space the appropriate amount of times so you're indented to the right level, then you should be able to hit enter again without the shell ending your definition and displaying >>> again.
You should also be to redefine the class in the shell, so I'm not quite sure what you mean by "an error was thrown" -- it might be helpful if you were to edit your post to include the specific stack trace.
I found this python code on the forums as an answer to something that relates to my problem. I don't really understand python, so can somebody tell me why this isn't working?
(Some background information: I have a web form that get automatically emailed to openERP, which then automatically creates a lead. However, when a lead is created, info like phone and name do not get read from the email and sorted into their corresponding fields in the lead's form.)
# You can use the following variables:
# - self: ORM model of the record on which the action is triggered
# - object: browse_record of the record on which the action is triggered if there is one, otherwise None
# - pool: ORM model pool (i.e. self.pool)
# - time: Python time module
# - cr: database cursor
# - uid: current user id
# - context: current context
# If you plan to return an action, assign: action = {...}
def parse_description(description):
'''
there is parse function
It is example for parsing messages like this:
Name: John
Phone: +100500
'''
fields=['Name','Phone']
_dict={}
description=description.lower()
for line in description.split('\n'):
for field in fields:
if field in line:
split_line=line.split(':')
if len(split_line)>1:
pre_dict[field]=line.split(':')[1]
return dict
lead=self.browse(cr,uid,context['active_id'],context=context)
description=lead['description']
_dict=parse_description(description)
self.write(cr,uid,context['active_id'],{
'partner_name':_dict.get('name'),
'contact_name':_dict.get('name'),
'phone':_dict.get(u'phone'),
'mobile':_dict.get(u'phone')})
Update:
I got these traceback while I am fetching mail
2014-07-01 13:39:40,188 4992 INFO v8_demo openerp.addons.mail.mail_thread: Routing
mail from Atul Jain <jain.atul43#gmail.com> to jain.atul10#hotmail.com with
Message-Id <CAG=2G76_SRthL3ybGGyx2Lai5H=RMNxUOjRRR=+5-ODrcgtEZw#mail.gmail.com>:
fallback to model:crm.lead, thread_id:False, custom_values:None, uid:1
2014-07-01 13:39:40,445 4992 ERROR v8_demo openerp.addons.fetchmail.fetchmail:
Failed to fetch mail from imap server Gmail.
Traceback (most recent call last):
File "/home/atul/openerp-8/openerp/addons/fetchmail/fetchmail.py", line 206, in
fetch_mail
action_pool.run(cr, uid, [server.action_id.id], {'active_id': res_id, 'active_ids'
:[res_id], 'active_model': context.get("thread_model", server.object_id.model)})
File "/home/atul/openerp-8/openerp/addons/base/ir/ir_actions.py", line 967, in run
res = func(cr, uid, action, eval_context=eval_context, context=run_context)
File "/home/atul/openerp-8/openerp/addons/base/ir/ir_actions.py", line 805,
in run_action_code_multi
eval(action.code.strip(), eval_context, mode="exec", nocopy=True) # nocopy allows
to return 'action'
File "/home/atul/openerp-8/openerp/tools/safe_eval.py", line 254, in safe_eval
return eval(c, globals_dict, locals_dict)
File "", line 14, in <module>
File "", line 4, in parse_description
ValueError: "'bool' object has no attribute 'lower'" while evaluating
u"def parse_description(description):
fields=['name','phone']
_dict={}
description=description.lower()
for line in description.split('\\n'):
for field in fields:
if field in line:
split_line=line.split(':')
if len(split_line)>1:
_dict[field]=split_line[1]
return _dict
lead=self.browse(cr,uid,context['active_id'],context=context)\ndescription=lead['description']
_dict=parse_description(description)
self.write(cr,uid,context['active_id'],{ 'partner_name':_dict.get('name'), 'contact_name':_dict.get('name'),
'phone':_dict.get(u'phone'),
'mobile':_dict.get(u'phone')})"
Please help me in understanding the problem.
I've fixed the parse_description function:
def parse_description(description):
'''
there is parse function
It is example for parsing messages like this:
Name: John
Phone: +100500
'''
fields=['name','phone']
_dict={}
description=description.lower()
for line in description.split('\n'):
for field in fields:
if field in line:
split_line=line.split(':')
if len(split_line)>1:
_dict[field]=split_line[1]
return _dict
I changed the fields values to lower case because all operations on the description are on description.lower().
On the line pre_dict[field]=line.split(':')[1], you are splitting line to get your result. This has already been done: split_line=line.split(':') so you can just replace the pre_dict line with pre_dict[field]=split_line[1]
On that same line you are using a variable, pre_dict, which hasn't been referenced before. I think you mean to use _dict so the line should be _dict[field]=split_line[1]
The function returns dict which is a type, not a variable. You probably want it to return the dictionary which contains the field data, so it should return _dict instead; otherwise you'll always get the result <type 'dict'>
As for the remaining code, there's not enough context for me to understand what's happening or what's wrong. At least the parse_description function should be working now.
Following is the models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User)
belongs_to_user_category = models.ForeignKey(UserCustomCategory, null=True, blank=True)
class UserHistory(models.Model):
date_time = models.DateTimeField()
user = models.ForeignKey(UserProfile, null=True, blank=True)
points_earned = models.DecimalField(max_digits=5, decimal_places=3)
as is clear, userhistory is a foreign key to UserProfile. For the test purpose i wanted to update the points of the user whose name starts with a
I wrote the following code in the python shell:
from myapp.models import *
uobj = UserProfile.objects.all()
for i in uobj:
if i.user.username[0] == 'a':
b = UserHistory.objects.create(user=i)
b.points_earned = random.random(10, 100)
b.date_time = datetime.datetime.now()
b.save()
i have also tried b = UserHistory.objects.get_or_create(user=i) with same error
and i get the following error:
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (160, 0))
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (13, 0))
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (63, 0))
ERROR: Internal Python error in the inspect module.
Below is the traceback from this internal error.
Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/IPython/ultraTB.py", line 667, in text
locals,formatvalue=var_repr))
File "/usr/lib/python2.6/inspect.py", line 875, in formatargvalues
specs.append(strseq(args[i], convert, join))
File "/usr/lib/python2.6/inspect.py", line 830, in strseq
return convert(object)
File "/usr/lib/python2.6/inspect.py", line 872, in convert
return formatarg(name) + formatvalue(locals[name])
KeyError: 'connection'
IPython's exception reporting continues...
---------------------------------------------------------------------------
IntegrityError Traceback (most recent call last)
IntegrityError: (1048, "Column 'date_time' cannot be null")
When you use the create method of the default model manager in Django, it will also attempt to create that instance into the database and save it. You can do this in two ways, but I'll show you what you can do with your approach, which may help in some understanding.
First, you will want to create a UserHistory object, but don't actually save it. This is done by simply instantiating that model class with any default values you'd like:
b = UserHistory(user=i)
After that, you can set the other attributes.
b.points_earned = random.randint(10, 100)
b.date_time = datetime.datetime.now()
b.save()
And this will work. Because you're now saving b after you've set the date_time.
There are ways to improve this of course, you can simply create everything in one call since you're doing it in one logical step, like so:
b = UserHistory.objects.create(
user=i,
points_earned=random.randint(10, 100),
date_time=datetime.datetime.now(),
)
You can further improve this by reading the DateField docs for Django, which will give you some tips on how to set the default date to the current time.
Hope this helps!