Adding two objects with one django form - python

Just to mention, English is not my native language.
So my question is, I have a form in Python/Django, that adds a simple object with name and function, example:
Function: programmer
Name: Carlos
What I want to do is to make things simple for the user when he adds several users with the same function, so I thought, when the user do something like this...
Function: programmer
Name: Dean,Seth,Roman,Ross,Joey,Chandler
...my form would add 6 objects, but the problem is that when I do this, python/django always tries to use the same ID/PK(example: tries to add all 6 members with id/pk=1).
I've done a little manuever(in Brasil we call gambiarra), so my code does this(after splitting objects):
form2.name = nombre
form2.pk = primary+1
form2.save()
primary=form2.pk
This basically consists in using this var called primary to change the value of PK and saving to Postgres. It worked, now Dean is pk/id 1....Chandler is pk/id 6, and all in one form.
But, I'm not that lucky, so when I go to add another name, like George, the system tries to use pk=2.
Does anyone knows to resolve this thing without this manuever or how to improve this manuever to solve completely?
My code (just to remind, I'm a python beginner):
objnet = form.save(commit=False)
if ',' in objnet.netaddr:
listaips = objnet.netaddr.split(',')
codeon = 1
nomecomum=objnet.nome
for ip in listaips:
objnet.netaddr = ip
objnet.nome = nomecomum + "_" + str(codeon)
objnet.save()
codeon+=1
else:
objnet.save()
Explanation:
I have a form with an IP field(netaddr) and a char field(nome)....if contains a ',' in IP field, it will add more than one object, example:
nome = carlos
netaddr = 2.2.2.2,3.3.3.3
it should add carlos_1 in my DB with IP 2.2.2.2, and carlos_2 with IP 3.3.3.3. And the code really does that, but, he adds carlos_1 and then, he tries to add carlos_2, he does with the same PK, so instead of adding another element, he overwrites carlos_1, so in my DB now there's only carlos_2.
Thank you

You have such problem because objnet always link to one object (since form.save() returns object)
Quick fix:
if ',' in objnet.netaddr:
listaips = objnet.netaddr.split(',')
codeon = 1
for ip in listaips:
objnet = form.save(commit=False)
objnet.netaddr = ip
objnet.nome = objnet.nome + "_" + str(codeon)
objnet.save()
codeon+=1
else:
form.save()

Related

How to replace email domain misspellings

I manage a booking system where people enter their emails to book appointments. Unfortunately, many of the email addresses have typos, especially in the top-level domain. I'd like to implement a function to identify when the domain should be .com, which should be all cases where it starts with ".c".
I wrote the function and tested the individual lines, which seem to work. But when I run the function on a set of emails, it only returns the email with no ".c", meaning it only returns 'my_name_is#orange.org'. The ideal output would be:
['me.you#perp.com',
'appleorange#msn.edu.com',
'laughable#gmail.com',
'notfunny#pointdexter.com',
'very.latin...word#word.nutherwork.com',
'very.latin..word#word.nutherwork.com',
'my_name_is#orange.org']
Any help would be appreciated!
emails = ['me.you#perp.comp',
'appleorange#msn.edu.cot',
'laughable#gmail.copl',
'notfunny#pointdexter.com',
'very.latin...word#word.nutherwork.com',
'very.latin..word#word.nutherwork.cnm',
'my_name_is#orange.org']
def domain(emails):
for email in emails:
parse_mail = email.split('.')
parse_mail = parse_mail[-1]
if parse_mail[0] == "c":
email = email.replace(parse_mail,"com")
pass
return email
print(domain(emails))
It returns the email without "c" because that's the last one in the array.
Your routine "domain" only returns the last email in the array. If you put the org address higher up, it'll return an email with a "c".
I expect what you're looking for is:
def domain(emails):
for i in range(len(emails)):
parse_mail = emails[i].split('.')
if parse_mail[-1][0] == "c":
parse_mail = emails[i].split('.')[:-1]
parse_mail.append("com")
correct = '.'.join(parse_mail)
emails[i] = correct
pass
return emails
print(domain(emails))
But as Sembei Norimaki, mentioned - this will also auto-correct (erroneously) other extensions beginning with a 'c'.

Get author_id from mail_message in openERP

I'm trying to get a field from openERPs mail_message model using python code which is executed in a server action (so its not a module where I can debug! I cannot even print in this state) (when a new eMail is being fetched) but I am unable to get anything useful from it.
Basicly when someone is throwing me a email, a new Task is created by openERP. But the newely created ticket is not connected to the user which send me the mail.
When a new email is fetched, this server action gets executed.
In a table called mail_message you can then find the email (+ author_id, + email, + res_id (which is the id of the created Task), therefore I'd like to fetch the author_id from that table.
(A query would look like this:
SELECT author_id FROM mail_message WHERE type = 'email' AND res_id = '<Task.id>')
This is my current code
#Initialize object. That one points to the mail_message model.
mailMessage_obj = self.pool.get('mail.message')
#Created Id in project_task
myId = object.id
#browse whole object with that id
#message = mailMessage_obj.browse(cr,uid,[myId])
#Select field where
messageIds = mailMessage_obj.search(cr,uid,[('type','=','email'),('res_id','=',myId)],context=context)
if messageIds:
#messageRecord = mailMessage_obj.browse(cr,uid,[myId],context=context)
#object.write({'partner_id':messageRecord.author_id.id})
res = mailMessage_obj.read(messageIds, ['author_id'])
partnerId = res[0]
#Author id
#partnerId = message[0]['author_id']
#partnerId = message.author_id
#res = [(r['id'], r['author_id']) for r in messageRecord]
#partnerId = res
#partnerId = 259866
object.write({'partner_id':partnerId})
I dont know how to get my hands on the author_id properly. If I hardcode a ID and let it write to the database (last two lines) It'll work just fine, but I cant hardcode a users id. ;)
Could someone explain to me how its done correctly?
I dont know whether I should use .browse or .read or something else..
I think you have an error on you python method.
you wrote :
res = mailMessage_obj.read(messageIds, ['author_id'])
partnerId = res[0]
But read() method returns here a list of dict (because messageIds is a list). Then, you have not specified the field you wanted to retrieve from res variable, and finally, as author_id is a many2one, it returns something like this : (2, 'myusers').
You should have done :
res = mailMessage_obj.read(cr, uid, messageIds, ['author_id'])
partnerId = res[0]['author_id'][0]
Hope i helped you,
Greatings

db connection in form validation - WEB.PY - PYTHON

my first question here, perhaps a noob question but I really don't understand what I'm doing wrong, and I can't find any clue on the web.py documentation.
Is it possible to use a db select to validate a field?
What I'm doing:
I'm building a registration form, I'm having trouble with the username validation.
In every example I found, users are declared in a variable before the registration Class with code like this:
allowed = (
('jon','pass1'),
('tom','pass2')
)
and used in the validation like this:
form.Validator('Username already exists.', lambda x: x not in allowed)
Since I'm saving in db, I can change the allowed tuples with a db.select, but this mean the select is performed only once.
I want to check the users every time the POST is called, so I just replaced the "allowed" variable with a db.select this way:
form.Validator('Username already exists.', lambda x: x not in [o.usr for o in db.select('users',what='usr')])
If I test "x not in [o.usr..etc..etc..]" on the interpreter, this work..
>>> [o.usr for o in db.select('users',what='usr')]
0.0 (1): SELECT usr FROM users
[u'hhh', u'Fede', u'Vinz', u'Patro', u'Codino', u'Codino']
>>> x = "Fede"
>>> x not in [o.usr for o in db.select('users',what='usr')]
0.0 (2): SELECT usr FROM users
False
But when I run the code and I make a new registration with an existing username nothing happens.. as you can see the "Codino" username is been registered twice.
What I'm doing wrong?
..and more interesting: there is a smarter way to block the registration of an already used username?
Thanks,
Federico
I don't know if you already have an answer with this one since it's an old thread.
Here's what I did on checking if username already exist.
I create a validator such as these:
vuser_exist = form.Validator("Username already exist.", lambda u: u is None or model.get_user(u.username) is None)
register_form = form.Form(
form.Textbox("username", vuser_req, vuser_length, description="Username"),
form.Button("submit", type="submit", description="Register"),
validators = [vuser_exist],
)
In model.py
def get_user(user):
try:
return db.select('users', where='user=$user', vars=locals())[0]
except IndexError:
return None

Django Query doesn't match

I have the following Django Model:
class State(models.Model):
name = models.CharField(max_length=80,null=False)
latitude = models.CharField(max_length=80,null=False)
longitude = models.CharField(max_length=80,null=False)
def __unicode__(self):
return self.name
In my views.py file I've created the following method:
def getCoords(request):
if request.is_ajax():
if request.method == 'POST':
try:
state = request.POST['state'] #receives the state from JS
stateInstance = State.objects.get(name=state)
stateLat = stateInstance.latitude
stateLong = stateInstance.longitude
data = {"lat" : stateLat, "long" : stateLong}
except State.DoesNotExist:
return HttpResponse("No record")
return HttpResponse(simplejson.dumps(data)) #returns json
So I'm sending this method a param through ajax, let's say "California". The state variable gets the value (I have proved that) but the query doesn't get executed, it returns the query doesn't match message. I've tried with the following as well:
state = request.POST['state']
if state == 'California':
return HttpResponse("Yes!")
else:
return HttpResponse(state)
When this snippet returns the state it displays California which means state's value is correct but the query is not executed properly. I don't know what's going on. Any thoughts?
Make sure you're connecting to the correct database in your settings.py. Make sure the record actually does exist with plain old SQL.
SELECT * FROM [app_name]_state WHERE name = 'California';
Also, try it from the Django shell. python manage.py shell
>>> from [app_name].models import State
>>> s = State.objects.get(name='California')
>>> s
<State: California>
Make sure that what is actually being sent is sent as POST, and not accidentally a GET variable in the URL. Also, make sure that the post variable has no extra characters and that it is actually valid. A decent way to do that is to just print it to the console, or if AJAX, with Firebug.
# Single quotes added so you can see any extra spaces in the console
print "'%s'" % state

Asking for inputs in my script [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I would like to prompt the user to input number of users to run and email addresses to populate a csv file. I am getting some syntax error. How do I get this working ?
enter code here
import csv
# Define users
valid_input = False
while not valid_input:
users =raw_input('Number of users: ')
try:
users = range(0,int(users)
valid_input = True
except:
print "Invalid input"
pass
First_Name = ["Test"+str(user) for user in range(1, users+1)]
Last_Name = ["User%s" %user for user in users]
email_addresses = []
for user in users:
email= raw_input("Email domain for user %d: " %user)
email_addresses.append(last_names[user] + email)
Password = ["Password1" for user in users]
Group =["Test" for user in users]
Admin = ["Yes" for user in users]
# open a file for writing.
# open a file for writing.
with open('users.csv', 'wb') as csv_out:
writer = csv.writer(csv_out)
writer.writerows(zip(Email_Address, Password, First_Name, Last_Name, Group, Admin))
The line
Email_Address = (raw_input('Email_Address') [Last_Names + "Email_Address " for Last_Names inLast_Name]])
is invalid syntax. It's actually very difficult to tell what you're trying to do with that line, but it is very invalid syntax.
Also you seem to be misunderstanding iteration in python. On your first line you prompt for a single number and then try to iterate through it in multiple other places, which I'm guessing is pretty far from your intention.
users = (raw_input('number of users'))
will set users equal to a single string. I'm guessing that what you'd actually want is something more like this:
valid_input = False
while not valid_input:
users =raw_input('Number of users: ')
try:
users = range(0,int(users))
valid_input = True
except:
print "Invalid input"
pass
I've been reading through the code some more and while it seems to be pretty far from what you've written there, I'm guessing that you want to prompt the user for an email address for each user. If that is indeed the case, this is how you would do it:
email_addresses = []
for user in users:
email = raw_input("Email address for user %d: " %user)
email_addresses.extend([email + last_name for last_name in last_names])
Apparently I was mistaken about your intent, here's a solution for what you're looking for:
email_addresses = []
for user in users:
email= raw_input("Email domain for user %d: " %user)
email_addresses.append(last_names[user] + email)
Also, a couple style notes:
Try to keep all of your variable names as descriptive as possible. For instance, the last_name list you've got doesn't actually have last names, but holds user ids, so user_ids would be a better name
If you are going to adopt a pluralization nomenclature then make sure to pluralize lists and then make sure that the items can be referenced as the singular version instead of the other way around. For example:
last_name = [#some list]
[#something for last_names in last_name]
is just confusing. It should be:
last_names = [#some_list]
[#something for last_name in last_names]
Choose either snake case (like_this) or title case (likeThis) and stick with it. Nothing is more annoying than having to scroll through a lost codebase and figure out which case a particular variable is using.
I'm not into Python at all, but it seems to be 1 square bracket too much at the end of this line :
Email_Address = (raw_input('Email_Address') [Last_Names + "Email_Address " for Last_Names inLast_Name]])
After this line:
users = (raw_input('number of users'))
users is a string. Let's say you enter 100.
Now, you iterate over users:
First_Name = ["Test"+str(user) for user in users]
Strings are iterable, so user takes on the individual characters of the string '100'. That is, user will first be '1', then '0', then '0' again; you get Test1 then Test0 then Test0 rather than the 100 items I expect you expect.
You probably want to convert the input to an integer:
users = int(raw_input('number of users'))
And then iterate over a range (I'm assuming you want 1 through n rather than 0 through n-1:
First_Names = ["Test"+str(user) for user in range(1, users+1)]
I've also taken the liberty of changing the name of your variable to First_Names as what you have is a list of the first names, not a single first name.
Unfortunately, I don't really have the time to go into the rest of the problems with your code, of which there are many (including the question about input that you're actually asking), but that ought to get you started fixing it up.

Categories

Resources