how to use two tables inside a query? django - mysql

I am trying to use two tables inside one django query. But my query is resulting as "invalid JSON" format.
I want to filter data in Request table by (status="Aprv"). The Request table contains attributes 'from_id' and 'to_id'.
The uid is the id of the user who is currently logged in.
If the current user(uid) is having the 'from_id' of Requests table, the query should return data of 'to_id' from the 'RegUsers' table.
If the current user(uid) is having the 'to_id' of Requests table, the query should return data of 'from_id' from the 'RegUsers' table.
class frnds(APIView):
def post(self, request):
uid = request.data['uid']
ob = Requests.objects.filter(status="Aprv")
fid = ob.value('from_id')
tid = ob.value('to_id')
if fid == uid:
obj = RegUsers.objects.filter(u_id=tid)
else:
obj = RegUsers.objects.filter(u_id=fid)
ser = android_serialiser(obj, many=True)
return Response(ser.data)
I don't want to use foreign keys.
Please Do Help me Correct the syntax.
The error message

You may need to serialize your data to JSON using Django's serializer first:
serializers.serialize('json', obj)
note that you need to import the serializers first from django core
from django.core import serializers
To avoid using JSON serializing in every request I can recommend you to take a look on Parsers on official Django site
https://www.django-rest-framework.org/api-guide/parsers/

Related

control the empty data in django filter

I was coding the backend using Django. I am a beginner in Django. I used a filter to filter some post requests from the HTML form. here is the code.
#api_view(["POST"])
def program_search(request):
Data_List = []
MyFilter = CreateProgram.objects.filter(price__lte=request.POST['price'],
days=request.POST['days']).values()
...
but if I send a request from HTML form that one field of data be null the filter function cant handle it.
I hope you can make use of a simple if... clause to handle the situation
#api_view(["POST"])
def program_search(request):
price = request.POST.get('price')
days = request.POST.get("days")
if price and days:
qs = CreateProgram.objects.filter(price__lte=price, days=days)
else:
# in case of empty filter params from HTML, return empty QuerySet
qs = CreateProgram.objects.none()
# `qs` variable holds your result

how can I fetch the specific ids data( multiple ids are stored in list) using Django

I want to fetch data of multiple ids which is provided from the User Interface and these ids are stored in a list. So how can I retrieve the data of these ids using Django ORM?
When I try the following approach It returned nothing
def selectassess(request):
if request.method=='POST':
assess=request.POST.getlist("assess")
quesno=request.POST.getlist("quesno")
subid=request.POST.getlist("subid")
print(quesno,subid)
print(assess)
max_id = Sub_Topics.objects.all().aggregate(max_id=Max("id"))['max_id']
print(max_id)
pk = random.sample(range(1, max_id),3)
subss=Sub_Topics.objects.raw("Select * from Sub_Topics where id=%s",(str(pk),))
context4={
'subss':subss,
}
print(pk)
return render(request,"assessment.html",context)
By applying the below-mentioned approach I can get only one id-data which is specified by typing the index value. But I want to get the data of all ids which are stored in the list so how can I get my required output by using Django ORM
def selectassess(request):
if request.method=='POST':
assess=request.POST.getlist("assess")
quesno=request.POST.getlist("quesno")
subid=request.POST.getlist("subid")
print(quesno,subid)
print("youuuuu")
print(assess)
max_id = Sub_Topics.objects.all().aggregate(max_id=Max("id"))['max_id']
print(max_id)
pk = random.sample(range(1, max_id),3)
sub = Sub_Topics.objects.filter(pk=pk[0]).values('id','subtopic')
context4={
'sub':sub,
}
print(pk)
return render(request,"assessment.html",context4)
You can use filter(pk__in=pk).
Try:
list_of_ids = random.sample(range(1, max_id),3)
sub = Sub_Topics.objects.filter(id__in=list_of_ids).values('id','subtopic')

Consuming JSON API data with Django

From a Django app, I am able to consume data from a separate Restful API, but what about filtering? Below returns all books and its data. But what if I want to grab only books by an author, date, etc.? I want to pass an author's name parameter, e.g. .../authors-name or /?author=name and return only those in the json response. Is this possible?
views.py
def get_books(request):
response = requests.get('http://localhost:8090/book/list/').json()
return render(request, 'books.html', {'response':response})
So is there a way to filter like a model object?
I can think of three ways of doing this:
Python's filter could be used with a bit of additional code.
QueryableList, which is the closest to an ORM for lists I've seen.
query-filter, which takes a more functional approach.
1. Build-in filter function
You can write a function that returns functions that tell you whether a list element is a match and the pass the generated function into filter.
def filter_pred_factory(**kwargs):
def predicate(item):
for key, value in kwargs.items():
if key not in item or item[key] != value:
return False
return True
return predicate
def get_books(request):
books_data = requests.get('http://localhost:8090/book/list/').json()
pred = filter_pred_factory(**request.GET)
data_filter = filter(pred, books_data)
# data_filter is cast to a list as a precaution
# because it is a filter object,
# which can only be iterated through once before it's exhausted.
filtered_data = list(data_filter)
return render(request, 'books.html', {'books': filtered_data})
2. QueryableList
QueryableList would achieve the same as the above, with some extra features. As well as /books?isbn=1933988673, you could use queries like /books?longDescription__icontains=linux. You can find other functionality here
from QueryableList import QueryableListDicts
def get_books(request):
books_data = requests.get('http://localhost:8090/book/list/').json()
queryable_books = QueryableListDicts(books_data)
filtered_data = queryable_books.filter(**request.GET)
return render(request, 'books.html', {'books':filtered_data})
3. query-filter
query-filter has similar features but doesn't copy the object-orient approach of an ORM.
from query_filter import q_filter, q_items
def get_books(request):
books_data = requests.get('http://localhost:8090/book/list/').json()
data_filter = q_filter(books_data, q_items(**request.GET))
# filtered_data is cast to a list as a precaution
# because q_filter returns a filter object,
# which can only be iterated through once before it's exhausted.
filtered_data = list(data_filter)
return render(request, 'books.html', {'books': filtered_data})
It's worth mentioning that I wrote query-filter.

How to pass RawQuerySet result as a JSONResponse in DJango?

I have two models like this:
class McqQuestion(models.Model):
mcq_question_id = models.IntegerField()
test_id = models.ForeignKey('exam.Test')
mcq_right_answer = models.IntegerField()
class UserMcqAnswer(models.Model):
user = models.ForeignKey('exam.UserInfo')
test_id = models.ForeignKey('exam.Test')
mcq_question_id=models.ForeignKey('exam.McqQuestion')
user_answer = models.IntegerField()
I need to match the user_answer and mcq_right_answer. Able to do that by executing the below raw query.
rightAns=UserMcqAnswer.objects.raw('SELECT B.id, COUNT(A.mcq_question_id) AS RightAns\
FROM exam_mcqquestion AS A\
LEFT JOIN exam_usermcqanswer AS B\
ON A.mcq_question_id=B.mcq_question_id_id\
WHERE B.test_id_id=%s AND B.user_id=%s AND\
A.mcq_right_answer=B.user_answer',[test_id,user_id])
1) But the problem is that couldn't able to pass the result as JSONResponse because it says TypeError: Object of type 'RawQuerySet' is not JSON serializable
2) Is there any alternative to this raw query by using the objects and filtered querysets?
Django's serialize function's second argument can be any iterator that yields Django model instances.
So, in principle, you can use that raw SQL query that you worked on, using something like this:
query = """SELECT B.id, COUNT(A.mcq_question_id) AS RightAns\
FROM exam_mcqquestion AS A\
LEFT JOIN exam_usermcqanswer AS B\
ON A.mcq_question_id=B.mcq_question_id_id\
WHERE B.test_id_id=%s AND B.user_id=%s AND\
A.mcq_right_answer=B.user_answer"""%(test_id, user_id)
and then getting the json data you'll return, as:
from django.core import serializers
data = serializers.serialize('json', UserMcqAnswer.objects.raw(query), fields=('some_field_you_want', 'another_field', 'and_some_other_field'))
Good luck finding the best way to solve your issue
Edit: small fix, added an import
Using raw query is not recommended in Django.
When the model query APIs don’t go far enough, you can fall back to writing raw SQL.
In your case model query API can solve your problem. You can use the following view:
views.py
def get_answers(request):
test = Test.objects.get(name="Test 1")
answers = UserMcqAnswer.objects.filter(test_id=test, user=request.user).annotate(
is_correct=Case(
When(user_answer=F('mcq_question_id__mcq_right_answer'),
then=Value(True)),
default=Value(False),
output_field=BooleanField())
).values()
return JsonResponse(list(answers), safe=False)
Also you can consider Django Rest Framework for serialization of QuerySet.

Making the unique validator with Coland and SQLAlchemy

All I trying to do is simple blog website using Pyramid, SQLAlchemy. The form module I have chosen is Deform which uses Coland. So I have for now two fields in my form: name and url. Url creates by transliteration the name field, but it's nevermind. So I don't wanna have two articles with the same urls. I need somehow make the validator with Colland I think. But the problem is the validator performs per field, but not per Model record. I mean if I'd make validator for url field, I dont have information in my method about another fields, such as id or name, so I couldn't perform the validation.
For now I have there couple of strings I created for two hours =)
from slugify import slugify
def convertUrl(val):
return slugify(val) if val else val
class ArticleForm(colander.MappingSchema):
name = colander.SchemaNode(colander.String())
url = colander.SchemaNode(colander.String(),
preparer=convertUrl)
Actually, I thought I should perform such validation on a model level, i.e. in SQLAlchemy model, but of course futher rules don't work, because such rules exist mainly for making SQL scripts (CREATE TABLE):
class Article(TBase, Base):
""" The SQLAlchemy declarative model class for a Article object. """
__tablename__ = 'article'
id = Column(Integer, primary_key=True)
name = Column(Text, unique=True)
url = Column(Text, unique=True)
Actually my question doesn't refer neither to Deform nor to Colander, this validation must be performed at SQLAlchemy level, here's what i've come to:
#validates('url')
def validate_url_unique(self, key, value):
check_unique = DBSession.query(Article)\
.filter(and_(Article.url == value, Article.id != self.id)).first()
if check_unique:
# Doesn't work
raise ValueError('Something went wrong')
# Neither doesn't work
# assert not check_unique
return value