Category based list View in django - python

I have two model 1 is category, 2nd is details and I want make a view where i can click on a category and the link should take me to the list only for the current category what i clicked.
my models are given:
class FoodCategory(models.Model):
categoryname = models.CharField(max_length=100)
categorydetails = models.CharField(max_length=1000)
categoryimage = models.ImageField(default='cat_def.jpg',
upload_to='catimg')
class Meta:
verbose_name = 'Food Category'
def __str__(self):
return self.categoryname
class FoodDetails(models.Model):
fromcategory = models.ForeignKey(FoodCategory,
on_delete=models.CASCADE)
foodname = models.CharField(max_length=100)
fooddetails = models.CharField(max_length=1000)
foodimage = models.ImageField(default='food_def.jpg',
upload_to='fodimg')
armodel = models.CharField(default='andy.sfb', max_length=50)
additiondate = models.DateTimeField(default=timezone.now)
addedby = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
verbose_name = 'Food Detail'
def __str__(self):
return self.fromcategory.categoryname + \
' - ' + self.foodname + \
' - ' + 'added by' + \
' - ' + self.addedby.username
def get_absolute_url(self):
return reverse('food-details', kwargs={'pk': self.pk})
views.py file:
from django.shortcuts import render
from food.models import FoodCategory, FoodDetails
from django.views.generic import ListView, DetailView
class FoodCategoryView(ListView):
model = FoodCategory
template_name = 'food/food-category.html'
context_object_name = 'food'
class FoodListView(ListView):
model = FoodDetails
template_name = 'food/food-list.html'
context_object_name = 'food'
ordering = ['-additiondate']
class FoodDetailsView(DetailView):
model = FoodDetails
template_name = 'food/FoodDetails_detail.html'
and my urls.py file also:
from django.urls import path, include
from . import views
from .views import FoodCategoryView, FoodListView, FoodDetailsView
# api url handler
urlpatterns = [
path('category/', FoodCategoryView.as_view(), name='food-
category'),
path('foodlist/', FoodListView.as_view(), name='food-list'),
path('foodlist/<int:pk>/', FoodDetailsView.as_view(),
name='food-details')
]
here is my all files and i just want know a specific way to get the current category based food details.

You can do this by defining get_queryset on a listview.
class FoodDetailsByCategory(ListView):
def get_queryset(self):
return FoodDetails.objects.filter(fromcategory_id=self.kwargs['category_id'])
with a simple URL:
path('category/<int:category_id>', FoodDetailsByCategory.as_view(), name='food_details_by_category')

Related

How i can realize multiple pagination(drf)

If I'll send get request like thisenter image description here, i need to have multiple pagination (LimitOffset and PageNumber).
models.py:
from django.db import models
class Products(models.Model):
title = models.CharField(max_length=255)
description = models.TextField(blank=True)
photo = models.ImageField(upload_to="photos/%Y/%m/%d/", null=True)
hashtag = models.CharField(max_length=255)
is_hit = models.BooleanField(default=False)
category = models.ForeignKey('Category', on_delete=models.PROTECT, null=True)
def __str__(self):
return self.title
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
views.py:
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from .models import *
from .serializers import ProductsSerializer
class PaginationProducts(PageNumberPagination):
page_size = 2
page_size_query_param = 'page_size'
max_page_size = 2
class ProductsAPIList(generics.ListCreateAPIView):
queryset = Products.objects.all()
serializer_class = ProductsSerializer
pagination_class = PaginationProducts
serializers.py
from rest_framework import serializers
from .models import *
class ProductsSerializer(serializers.ModelSerializer):
class Meta:
model = Products
fields = "__all__"
def get_photo_url(self, obj):
request = self.context.get('request')
photo_url = obj.fingerprint.url
return request.build_absolute_uri(photo_url)
I need something that can help API client choose number of page and quantity of posts on that page. Think that in this case i need NumberPagePagination and LimitOffsetPagination.
I think you don't need to create the custom pagination class.
from rest_framework.pagination import LimitOffsetPagination
class ProductsAPIList(generics.ListCreateAPIView):
queryset = Products.objects.all()
serializer_class = ProductsSerializer
pagination_class = LimitOffsetPagination
The offset value corresponds to the page * size in the original pagination and the limit value corresponds to the size.

Django dynamic URL with data from DB

Models.py
from django.db import models
# Create your models here.
class reviewData(models.Model):
building_name = models.CharField(max_length=50)
review_content = models.TextField()
star_num = models.FloatField()
class buildingData(models.Model):
building_name = models.CharField(max_length=50)
building_loc = models.CharField(max_length=50)
building_call = models.CharField(max_length=20)
views.py
# Create your views here.
from django.shortcuts import render
from rest_framework.response import Response
from .models import reviewData
from .models import buildingData
from rest_framework.views import APIView
from .serializers import ReviewSerializer
class BuildingInfoAPI(APIView):
def get(request):
queryset = buildingData.objects.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
class ReviewListAPI(APIView):
def get(request):
queryset = reviewData.objects.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
urls.py
from django.contrib import admin
from django.urls import path
from crawling_data.views import ReviewListAPI
from crawling_data.views import BuildingInfoAPI
urlpatterns = [
path('admin/', admin.site.urls),
path('api/buildingdata/', BuildingInfoAPI.as_view()),
#path('api/buildingdata/(I want to put building name here)', ReviewListAPI.as_view())
]
I am making review api.
I want to use building name as url path to bring reviews for specific buildings
For example, there are a, b, c reviews
a, b reviews are for aaabuilding
c reviews are for xxxbuilding
api/buildingdata/aaabuilding (only shows aaabuilding review)
{
building_name = aaabuilding
review_content = a
star_num = 5
building_name = aaabuilding
review_content = b
star_num = 3
}
api/buildingdata/xxxbuilding (only shows xxxbuilding review)
{
building_name = xxxbuilding
review_content = c
star_num = 4
}
I've searched some dynamic URL posts, but they were not that I want.
Also, I've posted a question before but there was no answer I was looking for.
Is there any way to bring building name into URL from db?
Please refer to the documentation on path converters. And usage of django's slugify function.
In your situation you will want a slug - but there are limitations to using a slug:
slugs must translate to some unique string, in your case building name. Therefore you should make sure that building name and slug are unique in your model.
You should add a slug field to the model - and also change the review model so it foreign keys to the building model:
from django.utils.text import slugify
class buildingData(models.Model):
building_name = models.CharField(max_length=50, unique=True)
slug = models.SlugField(unique=True)
building_loc = models.CharField(max_length=50)
building_call = models.CharField(max_length=20)
def save(self, *args, **kwargs):
self.slug = slugify(self.building_name)
return super().save(*args, **kwargs)
class reviewData(models.Model):
building = models.ForeignKey(buildingData, related_name='reviews', on_delete=models.CASCADE, null=False, blank=False)
review_content = models.TextField()
star_num = models.FloatField()
Then in your urls.py:
path('api/buildingdata/<slug:slug>/', ReviewListAPI.as_view())
Then in your Views.py:
class ReviewListAPI(APIView):
def get(self, request):
building = get_object_or_404(buildingData, slug=self.kwargs.get('slug')
queryset = building.reviews.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
Also review pep8 - your class names should really be BuildingData and ReviewData - and you problably dont need Data in the names either.

ImproperlyConfigured. View is missing a QuerySet. Define model, queryset, or override get_queryset()

This is the error i am having :- ImproperlyConfigured at /attendanceattendance/add
AddAttendance is missing a QuerySet. Define AddAttendance.model, AddAttendance.queryset, or
override AddAttendance.get_queryset().
This is my models.py
class StudentAttendance(models.Model):
StudentName = models.CharField(max_length=150)
StudentRoll = models.CharField(max_length=100)
lecturesAttended = models.IntegerField(null=True)
TotalLectures = models.IntegerField(null=True)
slug = models.SlugField(allow_unicode=True,null = True)
def __str__(self):
return self.StudentName
def save(self,*args,**Kwargs):
self.slug = slugify(self.StudentName)
super().save(*args,**Kwargs)
def get_absolute_url(self):
return reverse("home")
class Meta():
ordering = ['StudentName']
This is my view
class AddAttendance(generic.CreateView,LoginRequiredMixin):
form_model = forms.AttendanceForm
success_url = reverse_lazy('home')
template_name = 'attendance/attendance.html'
This is my urls
from django.conf.urls import url
from . import views
app_name = 'attendance'
urlpatterns = [
url(r'^attendance/add',views.AddAttendance.as_view(),name='attend')
]
enter image description here
Your view should look like this
class AddAttendance(generic.CreateView,LoginRequiredMixin):
form = forms.AttendanceForm
model = StudentAttendance
success_url = reverse_lazy('home')
template_name = 'attendance/attendance.html'

Django API: Problem with Displaying a Field

I am a beginner in Django. Right now, I am working with the APIs. I am facing a problem. I can't view one of the fields, called label, at http://127.0.0.1:8000/gameapi/. Here is the screenshot:
Here are my codes of serializers.py located inside gamreview folder.
from rest_framework import serializers
from .models import Game, Tags
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tags
fields = ['label']
class GameSerializer(serializers.ModelSerializer):
# label_tag = TagSerializer(many=True)
class Meta:
model = Game
fields = ['id', 'title', 'developer', 'platform']
fields = ['id', 'title', 'developer', 'platform','label_tag']
def create(self, validated_data):
label_tag_data = validated_data.pop('label_tag')
game = Game.objects.create(**validated_data)
for tags_data in label_tag_data:
Tags.objects.create(game=game, **tags_data)
return Game.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.developer = validated_data.get('developer', instance.developer)
instance.platform = validated_data.get('platform', instance.platform)
instance.tag = TagSerializer(read_only=True, many=True)
instance.save()
return instance
Here are my codes of models.py under gamreview folder:
from django.db import models
from django.template.defaultfilters import slugify
# Create your models here.
class Tags(models.Model):
label = models.CharField(max_length=20)
def __str__(self):
return self.label
class Game(models.Model):
title = models.CharField(max_length=100)
developer = models.CharField(max_length=100)
platform = models.CharField(max_length=50, default='null')
label_tag = models.ManyToManyField(Tags)
slug = models.SlugField(max_length=150, default='null')
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save(*args, **kwargs)
class Review(models.Model):
game = models.ForeignKey(Game, on_delete=models.CASCADE)
review = models.CharField(max_length=1000)
date = models.DateField(auto_now=True)
slug = models.SlugField(max_length=150, default='null')
def __str__(self):
return self.game
Here are my codes of views.py under gamreview folder:
from django.views import generic
from .models import Game
from rest_framework import generics
from .serializers import GameSerializer
# Create your views here.
class GameListView(generic.ListView):
template_name = 'gamereview/gamelist.html'
context_object_name = 'all_games'
def get_queryset(self):
return Game.objects.all()
class ReviewView(generic.DetailView):
model = Game
template_name = 'gamereview/review.html'
# class GameApiView(generics.ListAPIView):
class GameApiView(generics.ListCreateAPIView):
queryset = Game.objects.all()
serializer_class = GameSerializer
class GameDetailApiView(generics.RetrieveUpdateDestroyAPIView):
queryset = Game.objects.all()
serializer_class = GameSerializer
Here are my codes of urls.py under gamreview folder:
from . import views
from django.urls import path
app_name = 'gamereview'
urlpatterns = [
path('gamereview/', views.GameListView.as_view(), name='gamelist'),
path('gamereview/<slug:slug>/', views.ReviewView.as_view(), name='review'),
path('gameapi/', views.GameApiView.as_view(), name='gamelistapi'),
path('gameapi/<int:pk>/', views.GameDetailApiView.as_view()),
]
I don't get any error while running the server. However, the label field is not showing up.
How can I fix the issue?
You have declared fields twice in GameSerializer- Meta class. Delete the first one.
class GameSerializer(serializers.ModelSerializer):
# label_tag = TagSerializer(many=True)
class Meta:
model = Game
fields = ['id', 'title', 'developer', 'platform'] --> delete this
fields = ['id', 'title', 'developer', 'platform','label_tag']
Django rest framework relies on related_name attribute to the resolve foreign key fields.
I think just changing your Game model so would do it
label_tag = models.ManyToManyField(Tags, related_name="label")

How to use CreateView for the model that has a primary key from the first model that you have already used createview

Hi guys I'm trying to create a simple todo-list but I'm getting some troubles, first I want to create a task an inside of it I want to create some activities, that is the problem that I could not get done.
How can I create an activity using a CreateView end pass to it the pk from the task and after create how can reverse to same task detail
thanks a lot
models:
from django.db import models
from django.core.urlresolvers import reverse
class List(models.Model):
title = models.CharField(blank=True, max_length=100)
class Meta:
ordering = ['id']
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('task-detail', kwargs={'pk': self.pk})
PRIORITY_CHOICES = (
(1, 'Low'),
(2, 'Normal'),
(3, 'High')
)
class Item(models.Model):
title = models.CharField(blank=True, max_length=100)
created = models.DateTimeField(auto_now=False, auto_now_add=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
priority = models.IntegerField(choices=PRIORITY_CHOICES, default=2)
completed = models.BooleanField(default=False)
todo_list = models.ForeignKey(List)
class Meta:
ordering = ['-priority', 'title']
views:
class TaskDetailView(DetailView):
model = List
class TaskCreateView(CreateView):
model = List
fields = ['title']
success_url = '/home'
class TaskUpdateView(UpdateView):
model = List
fields = ['title']
template_name = 'core/update.html'
success_url = '/home'
class TaskDeleteView(DeleteView):
model = List
success_url = reverse_lazy('home')
class ActivityCreateView(CreateView):
model = Item
fields = 'title', 'priority', 'completed'
success_url = '/home'
class ActivityUpdateView(UpdateView):
model = Item
fields = 'title', 'priority', 'completed'
template_name = 'core/update_actvity.html'
success_url = '/home'
class ActivityDeleteView(DeleteView):
model = Item
success_url = reverse_lazy('home')
url :
from django.conf.urls import url, include
from django.contrib import admin
from core.views import ActivityCreateView, ActivityDeleteView, ActivityUpdateView
from core.views import TaskDetailView, TaskCreateView, TaskUpdateView, TaskDeleteView, Home, MyView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('allauth.urls')),
url(r'^$', Home.as_view(), name="index" ),
url(r'^home/$', MyView.as_view(), name="home" ),
url(r'^task/(?P<pk>[0-9]+)/$', TaskDetailView.as_view(), name='task-detail'),
url(r'^task/(?P<pk>[0-9]+)/update/$', TaskUpdateView.as_view(), name='task-update'),
url(r'^task/(?P<pk>[0-9]+)/delete/$', TaskDeleteView.as_view(), name='task-delete'),
url(r'^task/add/$', TaskCreateView.as_view(), name='task-create'),
]
in your form you can define a hidden input for the parent list and then in your form_valid method retrieve the parent using that pk... for example:
class ItemModelForm(forms.ModelForm):
list_pk = forms.IntegerField(widget=forms.HiddenInput)
class Meta:
model = Item
fields = ['...']
and then:
def form_valid(self, form):
parent_list = List.objects.get(pk=form.cleaned_data['list_pk'])
...
...

Categories