I created an update mutation as follows, with django==3.1.4 and graphene==2.1.8 :
# models.py
class CustomUser(AbstractUser):
# email = models.EmailField()
firebase_id = models.CharField(max_length=50, null=True)
nickname = models.CharField(max_length=50, null=True)
name = models.CharField(max_length=20, null=True)
gender = models.IntegerField(choices=Gender, default=3)
phone = models.CharField(max_length=20, null=True)
birthday = models.DateField(default=datetime(2020,1,1))
address = models.CharField(max_length=200, null=True)
profile_image = models.ImageField(default='default-avatar.png', upload_to='users/',
null=True, blank=True)
class UpdateMember(graphene.Mutation):
class Arguments:
firebase_id = graphene.String(required=True)
nickname = graphene.String()
name = graphene.String()
gender = graphene.Int()
phone = graphene.String()
birthday = graphene.Date()
address = graphene.String()
profile_image = graphene.String()
class Meta:
exclude = ["password"]
member = graphene.Field(MemberType)
success = graphene.Boolean()
# #login_required
#staticmethod
def mutate(root, info, firebase_id, **kwargs):
success = False
member_instance = CustomUser.objects.get(firebase_id=firebase_id)
if member_instance:
print(member_instance)
success = True
for k, v in kwargs.items():
member_instance.k = v
member_instance.save()
return UpdateMember(member=member_instance, success=True)
else:
return UpdateMember(member=None, success=False)
Running GQL below:
mutation {
updateMember(
firebaseId:"777",
name:"JJJJ")
{
success
}
}
Response:
{
"data": {
"updateMember": {
"success": true
}
}
}
But I checked the database, it seems no change in it, I think .save() should have done the work persisting changes to database......
Creating Member works fine. Using PostgresQL
Could anyone figure out why?
There is several issues in your code:
You can not assign your model fields using string like that. See this thread
for k, v in kwargs.items():
member_instance.k = v
member_instance.save()
Currently your member_instance.k has nothing to do with variable k inside for loop.
firebase_id field should be unique.
Currently you call CustomUser.objects.get(firebase_id=firebase_id) which is risky because firebase_id is not unique field. This may lead Multiple objects error if you have more than one CustomUsers saved with same id. To fix it, just define:
class CustomUser(AbstractUser):
# email = models.EmailField()
firebase_id = models.CharField(max_length=50, unique=True)
...
To check if your member_instance has really updated. You can for example print out the values before saving it and run some test cases before final implementation. For example:
if member_instance:
print(member_instance)
success = True
for k, v in kwargs.items():
member_instance.k = v
print(member_instance.k)
print(k)
print(getattr(member_instance, k))
member_instance.save()
Is it possible convert Suport Ticket to Project > Task.
Task Title = Suport subject, Task Description = Suport Description...
Example:
I use this modul https://www.odoo.com/apps/modules/9.0/website_support/
In support ticket i want add:
Below is new function def generate_task(self): how generate new TASK from that.
class WebsiteSupportTicketCompose(models.Model):
_name = "website.support.ticket.compose"
ticket_id = fields.Many2one('website.support.ticket', string='Ticket ID')
partner_id = fields.Many2one('res.partner', string="Partner", readonly="True")
email = fields.Char(string="Email", readonly="True")
subject = fields.Char(string="Subject", readonly="True")
body = fields.Html(string="Message Body")
template_id = fields.Many2one('mail.template', string="Mail Template", domain="[('model_id','=','website.support.ticket')]")
#api.onchange('template_id')
def _onchange_template_id(self):
if self.template_id:
values = self.env['mail.compose.message'].generate_email_for_composer(self.template_id.id, [self.ticket_id.id])[self.ticket_id.id]
self.body = values['body']
#api.one
def send_reply(self):
#Send email
values = {}
email_wrapper = self.env['ir.model.data'].get_object('website_support','support_ticket_reply_wrapper')
values = email_wrapper.generate_email([self.id])[self.id]
values['model'] = "website.support.ticket"
values['res_id'] = self.ticket_id.id
send_mail = self.env['mail.mail'].create(values)
send_mail.send()
#(Depreciated) Add to message history field for back compatablity
self.env['website.support.ticket.message'].create({'ticket_id': self.ticket_id.id, 'content':self.body.replace("<p>","").replace("</p>","")})
#Post in message history
#self.ticket_id.message_post(body=self.body, subject=self.subject, message_type='comment', subtype='mt_comment')
staff_replied = self.env['ir.model.data'].get_object('website_support','website_ticket_state_staff_replied')
self.ticket_id.state = staff_replied.id
#api.one
def generate_task(self):
values = {}
print(self.ticket_id.id)
print(self.email)
print(self.subject)
print(self.body.replace("<p>","").replace("</p>",""))
#How this data insert in new TASK
Any simple solution?
Try below code:
#api.multi
def generate_task(self,cr, uid, ids, context=None):
Task = self.pool["project.task"]
vals = {
"name": "TEST",
"description": "DESCRIPTION",
}
task_id = Task.create(cr,uid,vals,context=None)
task = Task.browse(cr,uid,task_id,context=None)
New to JSON/RUBY.
I have a Rest Service returning a JSON string and I would like to parse this into a Ruby Class. Is this recommended? I have tried the following example and get error- Can't convert String to Integer. This is for a rhomobile app I'm working on. I'm thinking POJO-->JSON-->Ruby. Any advice would be appreciated.
Ruby
##get_result = #params['body']
puts "##get_result : #{##get_result}"
data2 =##get_result
cust1 = data2["PolicyList"].map { |rd| PolicyList.new(rd["policyNbr"], rd["systemId"], rd["insuredName"],
rd["type"], rd["statusCd"], rd["statusDes"], rd["payorZipcode"],
rd["lastPaymentDate"], rd[lastPaymentAmount], rd["pastDueDate"], rd["pastDueAmount"],
rd["currentDueDate"], rd["currentDueAmount"], rd["eft"],
rd["suspenseAmt"], rd["expireTime"]) }
Class
class PolicyList
attr_accessor :policyNbr, :systemId, :insuredName,
:type, :statusCd, :statusDes, :payorZipcode,
:lastPaymentDate,:lastPaymentAmount,:pastDueDate,
:pastDueAmount,:currentDueDate,:currentDueAmount,:eft,
:suspenseAmt,:expireTime
def initialize(policyNbr, systemId,insuredName,type,statusCd,statusDes,payorZipcode,lastPaymentDate,lastPaymentAmount,
pastDueDate,pastDueAmount,currentDueDate,currentDueAmount,eft,suspenseAmt,expireTime)
#systemId = systemId
#insuredName = insuredName
#type = type
#statusCd = statusCd
#statusDes = statusDes
#payorZipcode = payorZipcode
#lastPaymentDate = lastPaymentDate
#lastPaymentAmount = lastPaymentAmount
#pastDueDate = pastDueDate
#pastDueAmount = pastDueAmount
#currentDueDate = currentDueDate
#currentDueAmount = currentDueAmount
#eft = eft
#suspenseAmt = suspenseAmt
#expireTime = expireTime
end
end
Returned JSON
[{"policyNbr":"0000001","systemId":"MB","insuredName":"JOHN DOE ","type":"MEMBERSHIP","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"07/12/2012","lastPaymentAmount":25.00,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":1362152384971},{"policyNbr":"0000002","systemId":"PC","insuredName":"JOHN DOE","type":"AUTO","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"02/15/2013","lastPaymentAmount":308.50,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":0},{"policyNbr":"0000003","systemId":"PC","insuredName":"JOHN DOE","type":"HOME","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"09/05/2012","lastPaymentAmount":149.00,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":0}]
You're getting an array of PolicyList objects, but there is no key called 'PolicyList'. I think you need this:
cust1 = data2.map { |rd| PolicyList.new(rd["policyNbr"], rd["systemId"], rd["insuredName"],
rd["type"], rd["statusCd"], rd["statusDes"], rd["payorZipcode"],
rd["lastPaymentDate"], rd['lastPaymentAmount'], rd["pastDueDate"], rd["pastDueAmount"],
rd["currentDueDate"], rd["currentDueAmount"], rd["eft"],
rd["suspenseAmt"], rd["expireTime"]) }
To make it easier for you. Here is a complete example.
class PolicyList
attr_accessor :policyNbr, :systemId, :insuredName,
:type, :statusCd, :statusDes, :payorZipcode,
:lastPaymentDate,:lastPaymentAmount,:pastDueDate,
:pastDueAmount,:currentDueDate,:currentDueAmount,:eft,
:suspenseAmt,:expireTime
def initialize(policyNbr, systemId,insuredName,type,statusCd,statusDes,payorZipcode,lastPaymentDate,lastPaymentAmount,
pastDueDate,pastDueAmount,currentDueDate,currentDueAmount,eft,suspenseAmt,expireTime)
#systemId = systemId
#insuredName = insuredName
#type = type
#statusCd = statusCd
#statusDes = statusDes
#payorZipcode = payorZipcode
#lastPaymentDate = lastPaymentDate
#lastPaymentAmount = lastPaymentAmount
#pastDueDate = pastDueDate
#pastDueAmount = pastDueAmount
#currentDueDate = currentDueDate
#currentDueAmount = currentDueAmount
#eft = eft
#suspenseAmt = suspenseAmt
#expireTime = expireTime
end
end
require 'json'
json = <<-JSON
[{"policyNbr":"0000001","systemId":"MB","insuredName":"JOHN DOE ","type":"MEMBERSHIP","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"07/12/2012","lastPaymentAmount":25.00,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":1362152384971},{"policyNbr":"0000002","systemId":"PC","insuredName":"JOHN DOE","type":"AUTO","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"02/15/2013","lastPaymentAmount":308.50,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":0},{"policyNbr":"0000003","systemId":"PC","insuredName":"JOHN DOE","type":"HOME","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"09/05/2012","lastPaymentAmount":149.00,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":0}]
JSON
##get_result = JSON.parse(json)
puts "##get_result : #{##get_result}\n\n"
data2 =##get_result
cust1 = data2.map { |rd| PolicyList.new(rd["policyNbr"], rd["systemId"], rd["insuredName"],
rd["type"], rd["statusCd"], rd["statusDes"], rd["payorZipcode"],
rd["lastPaymentDate"], rd['lastPaymentAmount'], rd["pastDueDate"], rd["pastDueAmount"],
rd["currentDueDate"], rd["currentDueAmount"], rd["eft"],
rd["suspenseAmt"], rd["expireTime"]) }
puts cust1.inspect
I'm trying to create a custom attr_accessor, but can't seem to get it to work. Instead of returning the value assigned to the writer, it returns the instance variable. Any ideas?
class Object
def custom_attr_accessor(klass, attribute)
ivar = "##{attribute}".to_sym
writer_body = lambda { |arg| instance_variable_set(ivar, arg) }
reader_body = lambda { ivar }
klass.send(:define_method, "#{attribute}=".to_sym, &writer_body)
klass.send(:define_method, "#{attribute}".to_sym, &reader_body)
end
end
class Person
end
custom_attr_accessor(Person, :age)
me = Person.new
me.age = 100
puts me.age
=> #age
Just like you did a instance_variable_set, you need instance_variable_get:
reader_body = lambda { instance_variable_get(ivar) }
BTW, extending Object and passing a class is not very pretty. Try to make it Persion. custom_attr_accessor(:age), that would be much more OOP.