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.
Related
My Project Configuration is this. This is realated to Contact Form. Here I have two approach: Customer from frontend can only post (i.e. send message) and admin can only retrieve and list the contacts.
Models.py
class Contact(models.Model):
full_name = models.CharField(max_length=100)
email = models.EmailField()
phone_no = models.CharField(max_length=10, validators=[validate_phone_no])
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
def __str__(self):
return self.email
serializers.py
class ContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = [
'full_name',
'email',
'phone_no',
'message',
]
Views.py
class ContactViewset(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
queryset = Contact.objects.all()
search_fields = []
ordering_fields = []
ordering = []
http_method_names = ["options", "head", "get"]
serializer_class = ContactSerializer
class CustomerContactViewSet(viewsets.ModelViewSet):
permission_classes = [AllowAny]
queryset = Contact.objects.all()
http_method_names = ['post']
serializer_class = ContactSerializer
urls.py
router.register("contacts-detail", ContactViewset)
router.register("contact-form", CustomerContactViewSet)
My question is: Why DRF is generating the same url for both views although I have given different names for both:
'contact-form'----> for posting and
'contact-detail'--------> for listing the contacts
Both views are pointing to same Model - Is this the Reason?
Click Here to see generated api url
See last urls are same: and redirecting to "contact-form". and I know I can give base_name to seperate both.
But I wanted to know the mechanism behind generating same url:
If anyone could explain this? Clearly
The problem is with the way you have defined the router.register calls in your urls.py file.
The first argument of the router.register function is the base name for the viewset. This base name is used to generate the URL patterns for the viewset. If you use the same base name for multiple viewsets, then the router will generate the same URL pattern for both viewsets.
For example, in your code you have defined the following lines:
router.register("contacts-detail", ContactViewset)
router.register("contact-form", CustomerContactViewSet)
Here, you have used the base name "contacts-detail" for the ContactViewset and the base name "contact-form" for the CustomerContactViewSet. This will result in two different URL patterns being generated:
/contacts-detail/
/contact-form/
However, since both viewsets are using the same model (Contact), the router will generate the same set of URL patterns for both viewsets. This is why you are seeing the same URL patterns for both viewsets in your API.
To fix this problem, you can use different base names for the two viewsets. For example, you could use "contacts" for the ContactViewset and "customer-contacts" for the CustomerContactViewSet. This would result in the following URL patterns being generated:
/contacts/
/customer-contacts/
I'm new to flask and in order to refactor an existing route method on a Flask API, i'm looking for the best practice to reduce it and call method inside the route method.
Acutally the route is designed like that :
#qman.route('/add_report/', methods=['POST'])
def create_report():
"""
Check if data send throught http POST request, is correct based on the report
schema and not already recorded in the table report of the DB.
:param: data from POST request
:return: Ok, valide and imported -> 201, Correct but AlreadyKnown -> 208,
InvalideScheme -> 422
"""
jsonData = request.get_json()
reportSchema = ReportSchema()
try:
data = reportSchema.load(jsonData)
except ValidationError as validation_err:
return(validation_err.messages), 422
nameReportCheck = data["report_name"]
report = Report.query.filter_by(report_name=nameReportCheck).first()
if report is None:
# Create new report
report = Report(
report_name=nameReportCheck,
hostname=data["hostname"],
status=data["status"],
date=data["date"],
nb_analysis_erreur=data["nb_analysis_erreur"]
)
db.session.add(report)
db.session.commit()
NewResult = reportSchema.dump(Report.query.get(report.reportID))
return{"message" : "Created new report" , "report" : NewResult}, 201
else :
reportAlreadyKnown = reportSchema.dump(Report.query.get(report.reportID))
return{"message" : "This report is already in the DB", "report" : reportAlreadyKnown}, 208
In the facts i would like to call a function named valid_schema(_schema, _jsondata) to check if the data send throught POST request match with my schema of model Report().
This function return a Response() object with serialized data and a 200 code if it's serialization is possible or an error that i cath inside try/except with 400 error code.
def valid_schema(_schema, _jsondata):
schema = _schema()
try:
data = schema.load(_jsondata)
except ValidationError as validation_err:
response = Response(validation_err.messages, 422)
return response
response = Response(data, 200, mimetype="application/json")
return response
Then the route method call an other function named create_report(report_data) if valid_schema(_schema, _jsondata) return report_data and 200 code in response object.
With his args, this method check if the records is not already in the DB and if is not, he create a Report() object from report_data arg and insert this one as a new record into the DB.
In fact I guess I can easily call this method inside the route function but it seem weird and there is probably an other way that I can't find, maybe decorator ?
One possibility for refactoring is the use of webargs, Flask-Marshmallow and marshmallow-sqlalchemy.
With Flask-Marshmallow you can check the input by specifying fields and validators. Webargs offers you the option of validating the defined scheme in a decorator and passing it on to the route as an argument. Using marshmallow-sqlalchemy in combination, this is immediately converted into a database model.
The following example is based on your information and gives you a brief overview of the usage. By defining your own error handler, the error messages can also be sent as JSON. Use in blueprints, views or the like is possible.
from flask import Flask
from flask import jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from marshmallow.validate import Length, OneOf
from webargs.flaskparser import use_args
app = Flask(__name__)
db = SQLAlchemy(app)
ma = Marshmallow(app)
class Report(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, unique=True)
hostname = db.Column(db.String)
status = db.Column(db.String)
date = db.Column(db.DateTime)
nb_analysis_error = db.Column(db.String)
class ReportSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Report
load_instance = True
sqla_session = db.session
name = ma.Str(required=True, validate=Length(min=3))
hostname = ma.Str(required=True)
date = ma.DateTime(required=True)
status = ma.Str(required=True, validate=OneOf(['online', 'offline']))
nb_analysis_error = ma.Str(missing='Unknown Error')
#app.route('/add_report', methods=['POST'])
#use_args(ReportSchema(), location='json')
def add_report(report):
report_schema = ReportSchema()
_report = Report.query.filter_by(name=report.name).first()
if _report:
report_data = report_schema.dump(_report)
return jsonify(message='Already Reported', report=report_data), 208
else:
db.session.add(report)
db.session.commit()
report_data = report_schema.dump(report)
return jsonify(message='Created', report=report_data), 201
with app.app_context():
db.drop_all()
db.create_all()
I'm trying to use try and except in django; everything work perfect if the user exist but if the user doesn't exist instead of returning NULL; my function keep returning:
Userprofile matching query does not exist.
I know the user is not exist in table; I just want to not return anything instead of showing error page.
from django import template
from album.models import Album
from django.shortcuts import get_object_or_404, render
register = template.Library()
#register.inclusion_tag('album/user_album.html')
def userAlbumFunction(id):
try:
albums = Album.objects.filter(user_id = id)
except Album.DoesNotExist:
albums = None
return {'albums' : albums}
try:
albums = Album.objects.get(user_id = id)
except Album.DoesNotExist:
albums = None
pass
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'
}
I am attempting to use the Facebook-Python-Ads-SDK to automate reporting on Ad Account performance. I have successfully requested a report at the ad set level, however the output of the report is a Cursor object, where I would prefer it to be a json or csv. I have tried the "export_format" option in params but it does not seem to make any difference. The output looks like JSON, so I attempted to import the object as a dataframe in pandas using pd.read_json(result) but it gives off an error saying that the object type "Cursor" needs to be str or bytes.
Does anyone have any experience with this api that can help me out? My code is below.
def report_request(start_date,end_date):
fields = [
'date_start',
'account_name',
'adset_name',
'ad_name',
'impressions',
'clicks',
'spend'
]
params = {
'time_range': {
'since': start_time,
'until': end_time,
},
'level':'ad',
'export_format':'csv'
}
account_id = [<ACCOUNT_ID>]
adAccount = AdAccount('act_' + account_id)
api_batch = get_api().new_batch()
request = adAccount.get_insights(fields=fields, params=params, async=False, batch=api_batch)
result = request.execute()
return result