How to submit custom fields data by python wordpress xmlrpc - python-3.x

I use wp job manager on my website. when I tried to add listing by xmlrpc, everything is fine, but Categories and Location are empty.
Screenshot
Screenshot
My code is as below. Could you tell me what's wrong with my code?
Thanks
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods.posts import GetPosts
from wordpress_xmlrpc.methods import posts
from wordpress_xmlrpc import WordPressTerm
from wordpress_xmlrpc.methods import taxonomies
wp = Client('http://127.0.0.1/15wp/xmlrpc.php', 'admin', '123456')
# now let's create a new product
widget = WordPressPost()
widget.post_type = 'job_listing'
widget.title = 'Widgetlast02'
widget.content = 'This is the widgets description.'
widget.post_status = 'publish'
widget.custom_fields = []
widget.custom_fields.append({
'job_location': 'Newyork',
'job_listing_category': 'hotel'
})
widget.id = wp.call(posts.NewPost(widget))

The custom_fields attribute expects a list of dicts.
Within each dict, it expects values for key and value fields.
Here, key is the name of the custom field, and value is the value you want to assign to it.
Below is the snippet for your specific example.
widget.custom_fields = [
{
'key': 'job_location',
'value': 'Newyork'
},
{
'key': 'job_listing_category',
'value': 'hotel'
}
]

This is just a guess from looking at the documentation for WordPressPost in wordpress_xmlrpc:
(Emphasis mine)
class WordPressPost
Represents a post, page, or other registered custom post type in
WordPress.
id
user
date (datetime)
date_modified (datetime)
slug
post_status
title
content
excerpt
link
comment_status
ping_status
terms (list of WordPressTerms)
terms_names (dict)
custom_fields (dict)
enclosure (dict)
password
post_format
thumbnail
sticky
post_type
It expects custom_fields to be a dict - you're creating a list and then inserting a dict into that list:
widget.custom_fields = []
widget.custom_fields.append({
'job_location': 'Newyork',
'job_listing_category': 'hotel'
})
This will probably work better:
widget.custom_fields = {
'job_location': 'Newyork',
'job_listing_category': 'hotel'
}

Related

No CustomerOrder matches the query

I am trying the generate PDF's for customers who successfully pays for an item but I keep getting this error.
No CustomerOrder matches the query
Below are my codes.
views.py
#staff_member_required
def admin_order_pdf(request, order_id):
order = get_object_or_404(CustomerOrder, id=order_id)
html = render_to_string('orders/pdf.html', {'order': order})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = f'filename=order_{order_id}.pdf'
weasyprint.HTML(string=html).write_pdf(response, stylesheets=[weasyprint.CSS(settings.STATIC_ROOT + 'css/pdf.css')])
return response
urls.py
urlpatterns = [
path('', views.order_payout, name='order_payout'),
path('admin/order/<int:order_id>/pdf', views.admin_order_pdf, name='admin_order_pdf'),
path('confirm/', views.confirm_order, name='confirm_order'),
]
The get_object_or_404 method returns the message 'No object matches the given query' when it is unable to find any objects in the specified model using the given filter, which is id=order_id in this case.
Check this section from the documentation for more information on the function.

Capture Unique Constraint on POST in DRF

I have a model with a unique field like so:
models.py
class MyModel(...):
name = models.CharField(max_length=32, ...)
key = models.CharField(max_length=32, ...)
class Meta:
constraints = [
UniqueConstraint(
fields = ['name', 'key'],
...
),
]
If I send a POST request where name is more than 32 characters, I get back a proper error response:
{"name": ["Ensure this field has no more than 32 characters."]}
However, if I send a POST request where the combination of name and key is not unique, an exception is raised and no message is sent back to the client. How can I capture when a unique constraint is violated and send back a message to the client?
Found the solution, DRF provides UniqueValidators link:
from rest_framework.validators import UniqueTogetherValidator
class ExampleSerializer(serializers.Serializer):
# ...
class Meta:
# ToDo items belong to a parent list, and have an ordering defined
# by the 'position' field. No two items in a given list may share
# the same position.
validators = [
UniqueTogetherValidator(
queryset=ToDoItem.objects.all(),
fields=['list', 'position']
)
]

How can I access item description from my Stripe webhook?

I am using Stripe Checkout (Client & Server Integration) and I want to be able to access the item description from my web hook.
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'name': 'Name of Product',
'description': description,
'amount': 30,
'currency': 'gbp',
'quantity': 1,
}],
success_url='https://www.website.uk/success',
cancel_url='https://www.website.uk/cancel',
)
Description is a variable that holds my item description.
My web hook looks like this (straight from docs):
#require_POST
#csrf_exempt
def my_webhook_view(request):
payload = request.body
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
event = None
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
except ValueError as e:
# Invalid payload
return HttpResponse(status=400)
except stripe.error.SignatureVerificationError as e:
# Invalid signature
return HttpResponse(status=400)
# Handle the checkout.session.completed event
if event['type'] == 'payment_intent.succeeded':
session = event['data']['object']
# Fulfill the purchase...
return HttpResponse(status=200)
My question is, how can I access my "description" variable from within the web hook? (Will be accessing it after # Fulfill the purchase)
I can see it is part of the session object (https://stripe.com/docs/api/checkout/sessions/object) but I'm not sure how to access it?
Have tried:
description = session['display_items']['custom']['description']
But I'm getting a key_error on display_items even though it is listed in the docs as part of the session object.
I had a similar issue which may help others who end up here; the length of the line_items array is 1 and the object which holds the properties is at index [0], therefore:
session.line_items[0].description
should give one access to the properties and values

format string based on conditions

I am trying to create a mail body template dynamically based on some conditions.
body = """ New product has created by {user}
This can be viewed by clicking here {link}
Logs is here {link2}
"""
I need to format this string based on some conditions, like:
if 'user' in params:
body.format(user='username')
if 'link' in params:
body.format(link='new link')
if 'link2' in params:
body.format(link2='new link2')
I know I can do like below,
body.format(user='username',link='new link',link2='new link2')
But i have to do this based on the above conditions. Is there any way to achieve this in python.?
I have found this and this didn't
help me.
Thanks in advance.
Yeah, I said to use lambdas in my comment but defining a function would be better for expandability. Here's your code:
def format_template(*args):
user = 'default'
link = 'something'
link2 = 'something2'
if 'user' in args:
user = 'username'
elif 'link' in args:
link = 'link'
elif 'link2' in args:
link2 = 'link2'
body = f"""
New product has created by {user}
This can be viewed by clicking here {link}
Logs is here {link2}
"""
return body
What about something like this?
params.setdefault('user', 'unknown user')
params.setdefault('link', 'unknown link')
params.setdefault('link2', 'unknown log link')
body = """ New product has created by {user}
This can be viewed by clicking here {link}
Logs is here {link2}
""".format(**params)
Of course you can change the defaults ('unknown user', etc.) to whatever value you deem appropriate. If you're not allowed to modify params, you can also use params2=dict(params) and then operate on params2 instead.
What's wrong with the question you linked? This seems like it would work:
body = """ New product has created by {user}
This can be viewed by clicking here {link}
Logs is here {link2}
""".format(user='username' if 'user' in params else '???',
link='new link' if 'link' in params else '???',
link2='new link2' if 'link2' in params else '???')
You can try like this.
Here params is a dictionary so you can iterate over its items and do the replacement.
>>> def format(body, **params):
... for key, value in params.items():
... rep = "{" + key + "}"
... if rep in body:
... body = body.replace(rep, value)
... return body
...
>>>
>>> body = """ New product has created by {user}
... This can be viewed by clicking here {link}
... Logs is here {link2}
... """
>>>
>>> print(format(body, user='username'))
New product has created by username
This can be viewed by clicking here {link}
Logs is here {link2}
>>> print(format(body, link='new link'))
New product has created by {user}
This can be viewed by clicking here new link
Logs is here {link2}
>>> print(format(body, link2='new link2'))
New product has created by {user}
This can be viewed by clicking here {link}
Logs is here new link2
>>>
>>> print(format(body, link2='new link2', link="new link"))
New product has created by {user}
This can be viewed by clicking here new link
Logs is here new link2
>>> print(format(body, link2='new link2', link="new link", user="username"))
New product has created by username
This can be viewed by clicking here new link
Logs is here new link2
>>>

How do I serialise a nested dictionary with Marshmallow?

I'm new to marshmallow and flask etc.
I'm trying to learn by creating an API that consumes a jsonified python dictionary. The dictionary contains nested dictionaries like this. It also contains a few Null items.
{
"TITLE": "XXX",
"NAME": "Mongoose",
"TIME": "0430",
"USED": null,
"DESCRIPTION": "",
"WEAPONS": {
"HEAT": "Israel",
"RADAR": "Flat",
"CONV": {
"S": true,
"N": false,
"A": false
},
},
}
I simply want to consume this back into a dictionary type. Something like this on the POST action
fields_schema = FieldSchema(many=True)
field_schema = FieldSchema()
json_data = request.get_json(force=True)
if not json_data:
return {'message': 'No input data provided'}, 400
# Validate and deserialize input
try:
data = field_schema.load(json_data)
except ValidationError as e:
return e.messages, 422
Where data would simply be a nested dictionary.
It is defining the schema class that is causing me problems.
From what I can tell, when defining the schema, marshmallow doesnt have a JSON type and when I use fields.Dict I get the following error:
{
"meta": [
"Missing data for required field."
],
"TITLE": [
"Unknown field."
etc...
I'm not sure whether I should be looking at using a nested Schema or whether I am totally over complicating things.
My fields_schema currently looks like this:
class FieldSchema(ma.Schema):
id = fields.Integer()
meta = fields.Dict(required=True)
Any pointers would be greatly appreciated
If you're going to validate the nested object, you can use Marshmallow's fields.Nested functionality.
Using their example
from marshmallow import Schema, fields, pprint
class UserSchema(Schema):
name = fields.String()
email = fields.Email()
created_at = fields.DateTime()
class BlogSchema(Schema):
title = fields.String()
author = fields.Nested(UserSchema)
user = User(name="Monty", email="monty#python.org")
blog = Blog(title="Something Completely Different", author=user)
result = BlogSchema().dump(blog)
pprint(result)
# {'title': u'Something Completely Different',
# 'author': {'name': u'Monty',
# 'email': u'monty#python.org',
# 'created_at': '2014-08-17T14:58:57.600623+00:00'}}
Your need to define a schema from the root document though. Something like
class Widget(Schema):
TITLE = fields.String()
NAME = fields.String()
# ...
WEAPONS = fields.Nested(Weapon)
class Weapon(Schema):
HEAT = fields.String()
# ...
might get you going.

Resources