I have set up an API using the Flask-Peewee API library:
class ActivityResource(RestResource):
exclude = ('id', 'course')
class CourseResource(RestResource):
exclude = ('id')
class SessionResource(RestResource):
def get_query(self):
identifier = get_identifier()
student = Student.get(Student.identifier == identifier)
from = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
to = datetime(2014, 6, 15)
return self.model.select().where(Session.date.between(from, to)).join(Activity).join(Course).join(StuCouRel).join(Student).where(Student.id == student.id).order_by(Session.date, Session.begin_time, Session.end_time)
paginate_by = None
include_resources = {
'activity': ActivityResource,
'course': CourseResource
}
exclude = ('id')
this will output something like this:
[
{
"duration": 7200,
"activity": {
"name": "MyActivityName"
},
"course": {
"name": "MyCourseName"
},
"end_time": "18:00",
"begin_time": "16:00",
"date": "03-04-2014"
},
...
]
what I would like to get, however, is this:
[
{
"duration": 7200,
"activity": "MyActivityName",
"course": "MyCourseName",
"end_time": "18:00",
"begin_time": "16:00",
"date": "03-04-2014"
},
...
]
I have read the docs and tried reading the source code itself, but I can't really figure out how to make it work. Any help would be appreciated.
I made this work using the prepare_data() hook:
def prepare_data(self, obj, data):
data["activity"] = obj.activity.name
data["course"] = obj.course.name
return data
Related
I am a beginner who is learning Django using wagtail. I have a custom API model where I need to do 2 queries. I tried to return 2 queries at the same time with this code
def get_queryset(self):
return super().get_queryset().order_by('-first_published_at'), super().filter_queryset('story_type=Story')
and I am getting Attribute error 'str' object has no attribute 'model'
Here is my api.py
class ProdPagesAPIViewSet(BaseAPIViewSet):
renderer_classes = [JSONRenderer]
filter_backends = [FieldsFilter,
ChildOfFilter,
AncestorOfFilter,
DescendantOfFilter,
OrderingFilter,
TranslationOfFilter,
LocaleFilter,
SearchFilter,]
meta_fields = ["type","seo_title","search_description","first_published_at"]
body_fields = ["id","type","seo_title","search_description","first_published_at","title"]
listing_default_fields = ["type","seo_title","search_description","first_published_at","id","title","alternative_title","news_slug","blog_image","video_thumbnail","categories","blog_authors","excerpt","content","content2","tags","story_type"]
nested_default_fields = []
def get_queryset(self):
return super().get_queryset().order_by('-first_published_at'), super().filter_queryset('story_type=Story')
name = "stories"
model = AddStory
api_router.register_endpoint("stories", ProdPagesAPIViewSet)
With the order_by I am getting newest published stories first But I also want to filter story_type=Story. If I query this using URL then it works fine like ?story_type=Story
Here is the API response with the order_by query
{
"id": 5,
"meta": {
"type": "blog.AddStory",
"seo_title": "",
"search_description": "",
"first_published_at": "2022-09-19T23:27:12.895017Z"
},
"title": "Test Story",
"alternative_title": "Alternative Heading",
"blog_image": {
"id": 1,
"meta": {
"type": "wagtailimages.Image",
"detail_url": "http://localhost/api/v2/images/1/",
"download_url": "/127.0.0.1/media/original_images/tiktok_U4POKiL.jpeg"
},
"title": "tiktok"
},
"excerpt": "Test Excerpt",
"content": "<div class=\"block-full_richtext\"><p data-block-key=\"h053a\"> Test Story </p></div>",
"tags": [
"Test"
],
"news_slug": "eea1awauwc",
"story_type": "Story"
}
What I want is to filter story_type=Story & order_by('-first_published_at') at a same time, How can I do that?
Thanks a lot for reading.
def get_queryset(self):
return super().get_queryset().filter('story_type=Story').order_by('-first_published_at')
I am looking to search for list of different characters/string using graphene-django with single search query run.
class Query(graphene.ObjectType):
candidateInfo = graphene.List(CandidateType, search=graphene.String(),
first=graphene.Int(),
skip=graphene.Int(), last=graphene.Int(),)
def resolve_candidateInfo(self, info, search=None, first=None, last=None, skip=None,
**kwargs):
qs = Candidate.objects.all()
if search:
filter = (
Q(candidateName__icontains=search)|
Q(candidateEmail__icontains=search)|
Q(candidateSkills__icontains=search)
)
qs = qs.filter(filter)
return qs
Here the candidateName, candidateSkills, candidateEmail are in Candidate class with models.CharField
With a single string/character search i am getting correct output. But it fails with list of sting/characters.
Edited: Adding json sample:
[
{
"model": "api.candidate",
"pk": 1,
"fields": {
"candidateName" : "Jack",
"candidateEmail" : "Jack#gmail.com",
"candidateSkills" : ["machine learning", "Artificial Intelligence"]
}
},
{
"model": "api.candidate",
"pk": 2,
"fields":{
"candidateName" : "John",
"candidateEmail" : "John#gmail.com",
"candidateSkills" : ["python", "machine learning"]
}
},
{
"model": "api.candidate",
"pk": 3,
"fields":{
"candidateName" : "Smith",
"candidateEmail" : "Smith#gmail.com",
"candidateSkills" : ["python"]
}
}
]
If query goes in:
query{
candidateInfo(search: "python")
{
candidateName
candidateEmail
}
}
# output must contain data of John and Smith (from sample json)
Also if query is
query{
candidateInfo(search: ["python","artificial intelligence"])
{
candidateName
candidateEmail
}
}
#output must contain data of Jack, John and smith
Adding models of candidate
from django.db import models
class Candidate(models.Model):
candidateName = models.CharField(max_length=100)
candidateEmail = models.CharField(max_length=100)
candidateSkills = models.CharField(max_length=100)
def __str__(self):
return self.candidateSkills
You can run a for loop as such:
qs = Candidate.objects.all()
if search:
if type(search) == list:
qs_l = []
for search_item in search:
filter = (
Q(candidateName__icontains=search_item)|
Q(candidateEmail__icontains=search_item)|
Q(candidateSkills__icontains=search_item)
)
qs_l.append(qs.filter(filter))
qs = qs_l
else:
filter = (
Q(candidateName__icontains=search)|
Q(candidateEmail__icontains=search)|
Q(candidateSkills__icontains=search)
)
qs = qs.filter(filter)
return qs
view.py
class ListDoctor(generics.ListCreateAPIView):
queryset = DoctorList.objects.filter(h_code="h_0001")
serializer_class = DoctorListSerializer
def list(self, request):
doctor = DoctorList.objects.values()
return Response(
{
"doctor": doctor
}
)
data:
"doctor": [
{
"doctorname": "testname1",
"position": "ST",
"h_code_id": "h_0000",
"d_code": "d_0000"
},
{
"doctorname": "testname2",
"position": "CB",
"h_code_id": "h_0000",
"d_code": "d_0001"
},
{
"doctorname": "testname3",
"position": "CM",
"h_code_id": "h_0001",
"d_code": "d_0002"
},
{
"doctorname": "testname4",
"position": "GK",
"h_code_id": "h_0001",
"d_code": "d_0003"
}
]
I would like to change the above code like below.
"h_0000" [
{
"doctorname" : "testname1",
"position" : "ST",
"h_code_id: "h_0000",
"d_code" : "d_0000"
},
{
"doctorname" : "testname2"
"position" : "CB"
"h_code_id: "h_0000",
"d_code" : "d_0001"
}
"h_0001" [
{
"doctorname" : "testname3",
"position" : "CM",
"h_code_id: "h_0001",
"d_code" : "d_0002"
},
{
"doctorname" : "testname4"
"position" : "GK",
"h_code_id: "h_0001",
"d_code" : "d_0003"
}
How can I change the data above to look like below?
We sincerely appreciate those who respond.
h_code_id(h_0001, h_0002, h_0003...) will increase gradually. Therefore, it cannot be manually created.
I assume you want to transform the data in different format.
def list(self, request):
data = {}
doctors = DoctorList.objects.values()
for doctor in doctors:
try:
data[doctor["h_code_id"]].append(doctor)
except KeyError:
data[doctor["h_code_id"]] = [doctor]
return Response(data)
I am working with a JSON request.get that returns a list. I will like to save each individual object in the response to my models so I did this:
in views.py:
def save_ram_api(request):
r = requests.get('https://ramb.com/ciss-api/v1/')
# data = json.loads(r)
data = r.json()
for x in data:
title = x["title"]
ramyo_donotuse = x["ramyo"]
date = x["date"]
thumbnail = x["thumbnail"]
home_team_name = x["side1"]["name"]
away_team_name = x["side2"]["name"]
competition_name = x["tournament"]["name"]
ramAdd = ramSample.objects.create(title=title, ramyo_donotuse=ramyo_donotuse, date=date, thumbnail=thumbnail, home_team_name=home_team_name, away_team_name=away_team_name, competition_name=competition_name)
ramAdd.save()
return HttpResponse("Successfully submitted!")
This works fine except that it would only save the last objects on the list.
the JSON response list (as a random 60 objects at any time) would look something like:
[
{
"title": "AY - BasketMouth",
"ramyo": "AY de comedian"
"side1": {
"name": "Comedy Central",
"url": "https:\/\/www.rabithole.com\/laugh\/dave-chappel\/"
},
"side2": {
"name": "Basket Mouth",
"url": "https:\/\/www.rabithole.com\/laugh\/chris-rockie\/"
},
"tournament": {
"name": "Night of a thousand laugh",
"id": 15,
"url": "https:\/\/www.rabithole.com\/laugh\/chris-rockie\/"
},
"points": [
{
"nature": "Gentle",
"phrase": "Just stay"
},
{
"nature": "Sarcastic",
"phrase": "Help me"
}
]
},
{
"title": "Dave - Chris",
"ramyo": "Dave Chapelle"
"side1": {
"name": "Comedy Central",
"url": "https:\/\/www.rabithole.com\/laugh\/dave-chappel\/"
},
"side2": {
"name": "Chris Rockie",
"url": "https:\/\/www.rabithole.com\/laugh\/chris-rockie\/"
},
"tournament": {
"name": "Tickle me",
"id": 15,
"url": "https:\/\/www.rabithole.com\/laugh\/chris-rockie\/"
},
"points": [
{
"nature": "Rogue",
"phrase": "Just stay"
}
]
}
]
In this case my views.py will only save the last dictionary on the list, ignoring the other 59.
My question would be:
How do I get the views.py to save the entire objects on the list?
Notice that the "points" is also a list that contains one or more dictionaries, any help how to save this as well?
Your code is saving only the last object in the list because you are creating and saving the object outside of the loop. Try this,
def save_ram_api(request):
r = requests.get('https://ramb.com/ciss-api/v1/')
# data = json.loads(r)
data = r.json()
for x in data:
title = x["title"]
ramyo_donotuse = x["ramyo"]
date = x["date"]
thumbnail = x["thumbnail"]
home_team_name = x["side1"]["name"]
away_team_name = x["side2"]["name"]
competition_name = x["tournament"]["name"]
ramAdd = ramSample.objects.create(title=title, ramyo_donotuse=ramyo_donotuse, date=date, thumbnail=thumbnail, home_team_name=home_team_name, away_team_name=away_team_name, competition_name=competition_name)
ramAdd.save()
return HttpResponse("Successfully submitted!")
How do I get the views.py to save the entire objects on the list?
Notice that the "points" is also a list that contains one or more
dictionaries, any help how to save this as well?
Regarding your those questions
If you are using PostgreSQL as a database then you can use Django's built is JSONField and ArrayField for PostgreSQL database.
And if your database is not PostgreSQL you can use jsonfield library.
Does anyone know, how I can implement the following MongoDB query using a MongoEngine Raq-Query?
db.getCollection('subscribers').find({
'_id': ObjectId("579e60b0c525fd2037e8dd31"),
'history.content.read_process_msg': {
'$exists':true
},
'history.content.read_processed': {
'$exists':true
},
'history.content.read_processed': false
},
{'history.$':1})
I read, that the raw-query doesn't support projections and that one should use .only() instead. But the problem here is, that it returns all the empty documents also…
Any advice?
Edit: Here are my models and a sample document:
class Subscriber(Document):
service = StringField()
history = EmbeddedDocumentListField('SubscriberHistory')
def __str__(self):
return self.service
class SubscriberHistory(EmbeddedDocument):
action = StringField()
content = DictField()
def __str__(self):
return self.action
And the sample:
{
"_id" : ObjectId("579e60b0c525fd2037e8dd31"),
"service" : "foo",
"history" : [
{
"action" : "outbound",
"content" : {
"read_processed" : false,
"message_data" : {
"text" : "w00t?"
},
"read_process_msg" : {
"$ref" : "bots_messages",
"$id" : ObjectId("57a6529dc525fd8066ee25b3")
}
},
"created_at" : ISODate("2016-08-06T21:12:00.986Z")
}
]
}