Django Jsonresponse filtered queryset by id - json

My objective is to get the id and make a queryset filtered by id, as in the following code:
views.py
class MyProfile(TemplateView):
model = Reports
template_name = 'template.html'
def get_context_data(request, *args, **kwargs):
if kwargs.get('pk', None):
q = kwargs.get('pk', None)
queryset = Reports.objects.all().values('id','line_x','line_y',).filter(id = q)
data = list(queryset)
return JsonResponse(data, safe=False)
urls.py
url(r'^profiles/(?P<pk>\d+)/$', views.MyProfile.as_view())
It returns the following error:
context must be a dict rather than JsonResponse
Django 1.11.8

from django.http import JsonResponse
def different_function_name(request, *args, **kwargs):
if kwargs.get('pk', None):
q = kwargs.get('pk', None)
queryset = Reports.objects.all().values('id','line_x','line_y',).filter(id = q)
query_list = list(queryset)
return JsonResponse(query_list, safe=False)

Related

How may I convert a Many to Many field into JSON Format in Django

I am working with APIs based in REST Architecture. I know Django has a framework to work with this APIs but my homework is do it from scratch. I got an API of a movies site where users can go and search information about a bunch of movies and i am trying to get the data into JSON format from the model Movie which has a Many-to-Many relationship whith the Actor model. I am using Class-based views for this.
The code from my models.py and views.py files is nested below:
class Actor(models.Model):
full_name = models.CharField(max_length=125)
role = models.CharField(max_length=125)
def __str__(self):
return self.full_name
class Movie(models.Model):
ACTION = 'AC'
DRAMA = 'DR'
COMEDY = 'CM'
SCIENCE_FICTION = 'SF'
THRILLER = 'TR'
RELIGIOUS = 'RG'
GENRE_CHOICES = [
(ACTION, 'Accion'),
(DRAMA, 'Drama'),
(COMEDY, 'Comedy'),
(SCIENCE_FICTION, 'Ciencia Ficcion'),
(THRILLER, 'Triler'),
(RELIGIOUS, 'Religioso')
]
title = models.CharField(max_length=155, blank=False)
synopsis = models.TextField(max_length=1000, blank=True)
genre = models.CharField(max_length=100, choices=GENRE_CHOICES, default='', blank=False)
tag = models.JSONField(default=dict, blank=True)
actors = models.ManyToManyField(Actor, related_name='movies', blank=True)
def __str__(self):
views.py
from django.views import View
from django.http.response import JsonResponse
from .models import Movie
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
import json
class MovieView(View):
#method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def get(self, request, pk=0):
"""
Return the list of all movies, or a single movie
:param pk:
:param request:
:return:
"""
if pk > 0:
movies = list(Movie.objects.filter(pk=pk).values())
if len(movies) > 0:
movie = movies[0]
data = {'message': "Success", 'movie': movie}
else:
data = {'message': "Movie not found... "}
return JsonResponse(data)
else:
movies = list(Movie.objects.values('title', 'synopsis', 'genre', 'actors__full_name').order_by('pk'))
if len(movies) > 0:
data = {'message': "Success", 'movies': movies}
else:
data = {'message': "Movies not found ..."}
return JsonResponse(data)
def post(self, request):
"""
Create a new movie
:param request:
:return:
"""
json_data = json.loads(request.body)
Movie.objects.create(title=json_data['title'], synopsis=json_data['synopsis'], genre=json_data['genre'],
tag=json_data['tag'], actors=json_data['actors'])
data = {'message': "Success"}
return JsonResponse(data)
def put(self, request, pk):
"""
Update a single movie
:param request:
:param pk:
:return:
"""
json_data = json.loads(request.body)
movies = list(Movie.objects.filter(pk=pk).values())
if len(movies) > 0:
movie = Movie.objects.get(pk=pk)
movie.title = json_data['title']
movie.synopsis = json_data['synopsis']
movie.genre = json_data['genre']
movie.tag = json_data['tag']
movie.save()
data = {'message': "Success"}
else:
data = {'message': "Movie not found ..."}
return JsonResponse(data)
def delete(self, request, pk):
movies = list(Movie.objects.filter(pk=pk).values())
if len(movies) > 0:
Movie.objects.filter(pk=pk).delete()
data = {'message': "Success"}
else:
data = {'message': "Movie not found ..."}
return JsonResponse(data)

`category` and `tag` shared by multiple wagtail page types

I have a Django+Wagtail website, and have category and tag created to be applied to blog posts.
from taggit.models import Tag as TaggitTag
from taggit.models import TaggedItemBase
class PostList(RoutablePageMixin, Page):
template = "Post_List.html"
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel("intro")
]
subpage_types = [
"PostDetail",
]
parent_page_type = [
"HomePage",
]
# Each 'search / category / tag / author' will generate a separate 'PostList' page with its own 'context',
# hence for 'Pagination' for all 'PostList' pages, we only need to implement in 'get_context()'
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
# For Pagination
page_id = request.GET.get("page")
paginator = Paginator(self.posts, 3) # 'posts' is defined in 'def post_list()' and 'def get_posts()' as below.
try:
paginator_page = paginator.page(page_id)
except PageNotAnInteger:
paginator_page = paginator.page(1)
page_id = 1
except EmptyPage:
paginator_page = paginator.page(1)
page_id =1
context['paginator_page'] = paginator_page
context['total_num_pages'] = paginator.num_pages
# By default, Paginator.get_elided_page_range(number, *, on_each_side=3, on_ends=2)
context['elided_page_range'] = paginator.get_elided_page_range(page_id, on_each_side=5, on_ends=2)
return context
def get_posts(self):
return PostDetail.objects.descendant_of(self).live()
#route(r'^tag/(?P<tag>[-\w]+)/$')
def post_by_tag(self, request, tag, *args, **kwargs):
self.search_type = 'tag'
self.search_term = tag
self.posts = self.get_posts().filter(tags__name=tag)
return Page.serve(self, request, *args, **kwargs)
#route(r'^category/(?P<category>[-\w]+)/$')
def post_by_category(self, request, category, *args, **kwargs):
self.search_type = 'category'
self.search_term = category
self.posts = self.get_posts().filter(categories__category__name=category)
return Page.serve(self, request, *args, **kwargs)
#route(r'^user/(?P<user>[-\w]+)/$')
def post_by_user(self, request, user, *args, **kwargs):
self.search_type = 'user'
self.search_term = user
self.posts = self.get_posts().filter(owner__username=user)
return Page.serve(self, request, *args, **kwargs)
#route(r'^$')
def post_list(self, request, *args, **kwargs):
self.posts = self.get_posts()
return Page.serve(self, request, *args, **kwargs)
#route(r'^search/$')
def post_search(self, request, *args, **kwargs):
search_query = request.GET.get('q', None)
self.posts = self.get_posts()
if search_query:
self.posts = self.posts.filter(body__contains=search_query)
self.search_term = search_query
self.search_type = 'search'
return Page.serve(self, request, *args, **kwargs)
class PostDetail(Page):
template = "Post_Detail.html"
body = MarkdownField()
tags = ClusterTaggableManager(through="PostDetailTag", blank=True)
#register_snippet
class Category(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=100)
panels = [
FieldPanel("name"),
FieldPanel("slug"),
]
def __str__(self):
return self.name
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ["name"]
#register_snippet
class Tag(TaggitTag):
class Meta:
proxy = True
# Intermediate Models for ManyToMany Relationship
class PostDetailCategory(models.Model):
post = ParentalKey("PostDetail", on_delete=models.CASCADE, related_name="categories")
category = models.ForeignKey("Category", on_delete=models.CASCADE, related_name="post_details")
panels = [
SnippetChooserPanel("category"),
]
class Meta:
unique_together = ("post", "category")
class PostDetailTag(TaggedItemBase):
content_object = ParentalKey("PostDetail", on_delete=models.CASCADE)
Now, I am about to creating another wagtail page type "SurveyPoll", and want to have tag and category applied as well.
What is the best practice for this deployment, same tag and category applied to different wagtail page types via ManyToMany relationship ?
Which type of ManyToMany relationship deployment is better, tag or category ? Personally, I prefer the category way as it allows me to choose from a list of existing category in wagtail admin edit page.

How can I change the color on the like button in django?

I did create (like and dislike) in my project and I need it when someone clicks on the button. the color will change to blue
I saw something like that where I could create a variable called something like: is_liked = False, and I can place that in HTML by context to trigger it in (if condition) but it's not working with me so, How can I run the color on the like button?
views.py
# Detail question and Create comment
class QuestionDetail(DetailView, SingleObjectMixin):
template_name = 'community/question_view.html'
slug_field = 'ask_slug'
slug_url_kwarg = 'user_slug'
model = UserAsking
queryset = UserAsking.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['my_question'] = UserAsking.objects.get(title=self.object)
self_post = UserAsking.objects.get(title=self.object)
post_slug = UserAsking.objects.get(ask_slug=self_post.ask_slug)
context['summation'] = post_slug.likes.count() - post_slug.dislikes.count()
context['comment_form'] = CommentForm
comments_count = Comment.objects.filter(userasking=UserAsking.objects.get(title=self.object))
context['comments_count'] = comments_count.count()
# liked_post = User.objects.get(username=self.request.user.username).likes.exists()
# context['liked_post'] = liked_post
# disliked_post = User.objects.get(username=self.request.user.username).dislikes.exists()
# context['disliked_post'] = disliked_post
return context
def post(self, request, user_slug, *args, **kwargs):
my_question = UserAsking.objects.get(ask_slug=user_slug)
userprof = UserProfile.objects.get(userasking__ask_slug=user_slug)
comment_form = CommentForm(request.POST, instance=request.user)
name = "%s %s" % (self.request.user.first_name, self.request.user.last_name)
username = self.request.user.username
logo = self.request.user.userprofile.logo.url
c = CommentForm(self.request.POST).add_error('comment', 'error')
if comment_form.is_valid():
comment_form = Comment.objects.create(comment=self.request.POST.get('comment', None),
userasking_id=my_question.id,
userprofile_id=userprof.id,
name=name,
username=username,
logo=logo,
comment_slug=my_question.ask_slug
)
comment_form.save()
return redirect('community:question_view', comment_form.userasking.ask_slug)
return render(request, 'community/question_view.html', {'comment_form': comment_form,
'c': c})
# Like post function
class LikePost(View, SingleObjectMixin):
template_name = 'community/question_view.html'
def post(self, request, *args, **kwargs):
post = get_object_or_404(UserAsking, ask_slug=request.POST.get('post_slug'))
if post.dislikes.filter(username=request.user).exists():
post.dislikes.remove(request.user)
post.likes.add(request.user)
models.py
class UserAsking(models.Model):
userprofile = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
title = models.CharField(max_length=100, blank=False, help_text='Be specific and imagine you’re asking a question to another person')
question = models.TextField(max_length=500, blank=False, help_text='Include all the information someone would need to answer your question')
field = models.CharField(max_length=20, choices=CHOICE, default='Technology', help_text='Add the field to describe what your question is about')
date = models.DateTimeField(auto_now_add=True)
ask_slug = models.SlugField(max_length=100)
likes = models.ManyToManyField(User, related_name='likes', blank=True)
dislikes = models.ManyToManyField(User, related_name='dislikes', blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('community:question_view', kwargs={'user_slug': self.ask_slug})
def save(self, *args, **kwargs):
self.ask_slug = slugify(self.title)
super().save(*args, **kwargs)
elif post.likes.filter(username=request.user).exists():
post.likes.remove(request.user)
else:
post.likes.add(request.user)
return redirect(post.get_absolute_url())
# Dislike post function
class DisLikePost(View, SingleObjectMixin):
def post(self, request, *args, **kwargs):
post = get_object_or_404(UserAsking, ask_slug=request.POST.get('post_dislike_slug'))
if post.likes.filter(username=request.user).exists():
post.likes.remove(request.user)
post.dislikes.add(request.user)
elif post.dislikes.filter(username=request.user).exists():
post.dislikes.remove(request.user)
else:
post.dislikes.add(request.user)
return redirect(post.get_absolute_url())
how can I put the condition in the HTML page to check if is_liked is True or False?
In Django Html use template like this
{% if query_set.is_like %}
...do something
change back color like <h1 style:background:''blue></h1>
{% else %}
No change... <h1></h1>
{% endif%}
I had to add a condition to get_context where that way did work with me. this way I didn't see before but it works perfectly:
views.py
class QuestionDetail(DetailView, SingleObjectMixin):
template_name = 'community/question_view.html'
slug_field = 'ask_slug'
slug_url_kwarg = 'user_slug'
model = UserAsking
queryset = UserAsking.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['my_question'] = UserAsking.objects.get(title=self.object)
self_post = UserAsking.objects.get(title=self.object)
post_slug = UserAsking.objects.get(ask_slug=self_post.ask_slug)
context['summation'] = post_slug.likes.count() - post_slug.dislikes.count()
context['comment_form'] = CommentForm
comments_count = Comment.objects.filter(userasking=UserAsking.objects.get(title=self.object))
context['comments_count'] = comments_count.count()
context['is_liked'] = False
context['is_dislike'] = False
# context to like the post
if LikePost.as_view():
if post_slug.dislikes.filter(username=self.request.user).exists():
context['is_liked'] = False
elif post_slug.likes.filter(username=self.request.user).exists():
context['is_liked'] = True
else:
context['is_liked'] = False
# context to dis-like the post
if DisLikePost.as_view():
if post_slug.likes.filter(username=self.request.user).exists():
context['is_dislike'] = False
elif post_slug.dislikes.filter(username=self.request.user).exists():
context['is_dislike'] = True
else:
context['is_dislike'] = False
return context
def post(self, request, user_slug, *args, **kwargs):
my_question = UserAsking.objects.get(ask_slug=user_slug)
userprof = UserProfile.objects.get(userasking__ask_slug=user_slug)
comment_form = CommentForm(request.POST, instance=request.user)
name = "%s %s" % (self.request.user.first_name, self.request.user.last_name)
username = self.request.user.username
logo = self.request.user.userprofile.logo.url
c = CommentForm(self.request.POST).add_error('comment', 'error')
if comment_form.is_valid():
comment_form = Comment.objects.create(comment=self.request.POST.get('comment', None),
userasking_id=my_question.id,
userprofile_id=userprof.id,
name=name,
username=username,
logo=logo,
comment_slug=my_question.ask_slug
)
comment_form.save()
return redirect('community:question_view', comment_form.userasking.ask_slug)
return render(request, 'community/question_view.html', {'comment_form': comment_form,
'c': c})
# Like post function
class LikePost(View, SingleObjectMixin):
template_name = 'community/question_view.html'
def post(self, request, *args, **kwargs):
post = get_object_or_404(UserAsking, ask_slug=request.POST.get('post_slug'))
if post.dislikes.filter(username=request.user).exists():
post.dislikes.remove(request.user)
post.likes.add(request.user)
elif post.likes.filter(username=request.user).exists():
post.likes.remove(request.user)
else:
post.likes.add(request.user)
return redirect(post.get_absolute_url())
# Dislike post function
class DisLikePost(View, SingleObjectMixin):
def post(self, request, *args, **kwargs):
post = get_object_or_404(UserAsking, ask_slug=request.POST.get('post_dislike_slug'))
if post.likes.filter(username=request.user).exists():
post.likes.remove(request.user)
post.dislikes.add(request.user)
elif post.dislikes.filter(username=request.user).exists():
post.dislikes.remove(request.user)
else:
post.dislikes.add(request.user)
return redirect(post.get_absolute_url())
at this moment, I add a condition on the view I already handle as you see above in the QuestionDetail model.

How do I make my model's depdent fields appear in my JSON using Django serializers?

I'm using Django 2.0 and Python 3.7. I have the following models ...
from django.db import models
from address.models import AddressField
from phonenumber_field.modelfields import PhoneNumberField
from address.models import State
from address.models import Country
class CoopTypeManager(models.Manager):
def get_by_natural_key(self, name):
return self.get_or_create(name=name)[0]
class CoopType(models.Model):
name = models.CharField(max_length=200, null=False)
objects = CoopTypeManager()
class Meta:
unique_together = ("name",)
class Coop(models.Model):
name = models.CharField(max_length=250, null=False)
type = models.ForeignKey(CoopType, on_delete=None)
address = AddressField(on_delete=models.CASCADE)
enabled = models.BooleanField(default=True, null=False)
phone = PhoneNumberField(null=True)
email = models.EmailField(null=True)
web_site = models.TextField()
And then I created the following serializers ...
from rest_framework import serializers
from maps.models import Coop, CoopType
class CoopSerializer(serializers.ModelSerializer):
class Meta:
model = Coop
fields = ['id', 'name', 'type', 'address', 'enabled', 'phone', 'email', 'web_site']
def create(self, validated_data):
"""
Create and return a new `Snippet` instance, given the validated data.
"""
return Coop.objects.create(**validated_data)
def update(self, instance, validated_data):
"""
Update and return an existing `Coop` instance, given the validated data.
"""
instance.name = validated_data.get('name', instance.name)
instance.type = validated_data.get('type', instance.type)
instance.address = validated_data.get('address', instance.address)
instance.enabled = validated_data.get('enabled', instance.enabled)
instance.phone = validated_data.get('phone', instance.phone)
instance.email = validated_data.get('email', instance.email)
instance.web_site = validated_data.get('web_site', instance.web_site)
instance.save()
return instance
class CoopTypeSerializer(serializers.ModelSerializer):
class Meta:
model = CoopType
fields = ['id', 'name']
def create(self, validated_data):
"""
Create and return a new `CoopType` instance, given the validated data.
"""
return CoopType.objects.create(**validated_data)
def update(self, instance, validated_data):
"""
Update and return an existing `Snippet` instance, given the validated data.
"""
instance.name = validated_data.get('name', instance.name)
instance.save()
return instance
I'm trying to create an API to display my models as JSON. I created this views file
from maps.models import Coop
from maps.serializers import CoopSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class CoopList(APIView):
"""
List all coops, or create a new coop.
"""
def get(self, request, format=None):
coops = Coop.objects.all()
serializer = CoopSerializer(coops, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = CoopSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class CoopDetail(APIView):
"""
Retrieve, update or delete a coop instance.
"""
def get_object(self, pk):
try:
return Coop.objects.get(pk=pk)
except Coop.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
coop = self.get_object(pk)
serializer = CoopSerializer(coop)
return Response(serializer.data)
def put(self, request, pk, format=None):
coop = self.get_object(pk)
serializer = CoopSerializer(coop, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
coop = self.get_object(pk)
coop.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
However, my dependent model, CoopType, is not getting displayed as JSON. Only its primary key is getting displayed, e.g. ...
{
"id": 915,
"name": "Young Men's Educational Network",
"type": 10,
"address": 790,
"enabled": true,
"phone": null,
"email": null,
"web_site": "www.ymenchi.com/"
},
How do I get my dependent model to appear in my JSON?
Override the to_representation(...) method of the Serializer
class CoopSerializer(serializers.ModelSerializer):
# other code snippets
def to_representation(self, instance):
rep = super().to_representation(instance)
rep['type'] = CoopTypeSerializer(instance.type).data
return rep
Reference: DRF: Simple foreign key assignment with nested serializers?

Django Rest Framework - Add fields to JSON

Now I return a JSON file with the model fields and their values. I want to add some extra fields to the JSON that are not present in the model (I want to add a new field that specifies if an user can modify or not the diagnostic based on the permissions of the view). How I can do this?
models.py
class Diagnostic(models.Model):
Center = models.TextField(blank=True)
Author = models.TextField(blank=True)
Email = models.EmailField(blank=True)
Date = models.DateField(null = True, blank=True)
views.py
class DiagnosticViewSet(viewset.ModelViewSet):
model = Diagnostic
permission_classes = [GroupPermission]
serializers.py
class DiagnosticSerializer(serializers.ModelSerializer):
class Meta:
model = Diagnostic
Add this to your views
def list(self, request, *args, **kwargs):
response = super(Classname, self).list(request, *args, **kwargs)
try:
response.data['permission'] = 'give your permission'
except:
pass
return response
You add them to the serializer.
class DiagnosticSerializer(serializers.ModelSerializer):
auth_status = serializers.SerializerMethodField('get_auth_status')
class Meta:
model = Diagnostic
def get_auth_status(self, obj):
if obj.has_auth():
return True
return False
You have to use following code for the url localhost/diagnostics/1
from rest_framework.response import Response
def retrieve(self, request, *args, **kwargs):
self.object = self.get_object()
serializer = self.get_serializer(self.object)
data = serializer.data
data['permission'] = 'give your permission'
return Response(data)