How can I delete cache_page in Django? - caching

I cached the view using cache_page in Django. But I want to clear the cache_page when a model in my view is updated.
views.py
#method_decorator(cache_page(168 * 3600,), name="dispatch")
class DashboardView(APIView):
permission_classes = [AllowAny]
def get(self, request):
m1 = Model1.objects.all()
m1_serializer = Model1Serializer(sliders, many=True)
m2 = Model2.objects.all()
m2_serializer = Model2Serializer(
collections, many=True
)
m3 = Model3.objects.all()
m3_serializer = Model3Serializer(categories, many=True)
response = {
"m1": m1_serializer.data,
"m2": m2_serializer.data,
"m3": m3_serializer.data,
}
return Response(response)
If a new record is added to any of these models, cache_page should be deleted.
signals.py
#receiver(post_save, sender=Model1)
def clear_cache_when_update_model1(
sender, instance, created, **kwargs
):
if created:
pass
#receiver(post_save, sender=Model2)
def clear_cache_when_update_model2(
sender, instance, created, **kwargs
):
if created:
pass
#receiver(post_save, sender=Model3)
def clear_cache_when_update_model3(
sender, instance, created, **kwargs
):
if created:
pass
I couldn't find the key of cache_page and couldn't find how to clear cache_page.

Related

Is there a way to call pagination methods get_next_link and get_previous_link in DRF viewset?

I want to add additional values ​​to the pagination response in my viewset and keep the fields what already there. I was able to add count, but i can`t add next and previous urls to response, is where a way to call pagination_class methods in viewset.
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(queryset, many=True)
return self.get_paginated_response(serializer.data)
else:
status_count = Vps.objects.all().aggregate(
started=Count("status", filter=Q(status="started")),
blocked=Count("status", filter=Q(status="blocked")),
stopped=Count("status", filter=Q(status="stopped"))
)
serializer = self.get_serializer(queryset, many=True)
status_count["results"] = serializer.data
return Response(status_count)
def get_paginated_response(self, data):
status_count = Vps.objects.all().aggregate(
started=Count("status", filter=Q(status="started")),
blocked=Count("status", filter=Q(status="blocked")),
stopped=Count("status", filter=Q(status="stopped"))
)
pagination = self.pagination_class()
page = self.paginate_queryset(data)
return Response(OrderedDict([
('count', pagination.get_count(data)),
('next', self.pagination_class.get_next_link),
('previous', self.pagination_class.get_previous_link),
('started', status_count["started"]),
('blocked', status_count["blocked"]),
('stopped', status_count["stopped"]),
('results', page)
]))
I was able to solve this by creating custom pagination class
class VpsLimitOffsetPagination(LimitOffsetPagination):
def get_paginated_response(self, data):
status_count = Vps.objects.all().aggregate(
started=Count("status", filter=Q(status="started")),
blocked=Count("status", filter=Q(status="blocked")),
stopped=Count("status", filter=Q(status="stopped"))
)
return Response(OrderedDict([
('count', self.count),
('started', status_count["started"]),
('blocked', status_count["blocked"]),
('stopped', status_count["stopped"]),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))

SerializerMethodField doesn't work on DRF

Here is the simplified verison of the Serializer what I have:
class CommentSerializer(serializers.HyperlinkedModelSerializer):
def __init__(self, *args, **kwargs):
init = super().__init__(*args, **kwargs)
return init
username = serializers.ReadOnlyField(source='user.username')
user_id = serializers.ReadOnlyField(source='user.id')
user = UserSerializer(read_only=True)
url_field_name = 'url_api'
# and more definitions
content_type_id = serializers.IntegerField()
site_id = serializers.SerializerMethodField('_siteId')
def _siteId(self, threadedcomment):
site_id = settings.SITE_ID
return site_id
class Meta:
model = ThreadedComment
fields = ('url_api','url','id','title','tree_path','comment','submit_date','submit_date_unix','submit_date_humanized','root_id','is_removed',
'parent_id','last_child_id','newest_activity','depth','username','user_id','object_pk','content_type_id','user',
'site_id',
)
read_only_fields = ('id','title','tree_path','submit_date','root_id','is_removed',
'parent_id','last_child_id','newest_activity','depth','username','user_id',
# 'site_id',
)
class CommentViewSet(viewsets.ModelViewSet):
queryset = ThreadedComment.objects.all().annotate().all()
serializer_class = CommentSerializer
permission_classes = []
filter_backends = [filters.OrderingFilter]
def filter_queryset(self, queryset):
return queryset
def list(self, request):
return super().list(request)
def perform_create(self, serializer):
serializer.save(user=self.request.user)
# site_id = settings.SITE_ID
# serializer.save(user=self.request.user, site_id=site_id, )
return super().perform_create(serializer)
Now I make an http post request on the api as i.e.:
axios.post('/api/comments/', {
"comment":"test.",
"object_pk":34,
"content_type_id":12,
},
It shows me an error:
500 (Internal Server Error)
IntegrityError: NOT NULL constraint failed: django_comments.site_id
The problem (a pure question) is, why the SerializerMethodField doesn't work? I put a breakpoint on the site_id = settings.SITE_ID line, but it doesn't hit, which means the line hasn't even executed.
I also tried putting a set of lines (the commented lines) on perform_create, reading a SO post, but the result is the same, the same error, NOT NULL constraint failed.
I'm certainly passing a value, but it shows it's a null value, saying nothing is passed, what this means? What am I donig wrong here? Thanks.

'InMemoryUploadedFile' object is not callable

While uploading the csv file showing "'InMemoryUploadedFile' object is not callable " this error, i want to import the csv file data into database using APIview.
Here My Apiview
class UploadViewSet(APIView):
parser_classes = (MultiPartParser, FormParser)
permission_classes = (AllowAny,)
serializer_class= UploadSerializer
def post(self, request, *args, **kwargs):
serializer = UploadSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
file = serializer.validated_data['File']
reader = csv.reader(file('file','r'))
for row in reader():
new_company = Company(
name=row['name'],
hr_name=row['hr_name'],
hr_email=row['hr_email'],
hr_verified=row['hr_verified'],
user_id=row['user_id'],
primary_phone=row['primary_phone'],
comments=row['comments'],
)
new_company.save()
return Response({"status": "success"},status.HTTP_201_CREATED)

Updating object using super().update()

I have an object, whose attributes I would like to update. Right now, I am able to update a single attribute eg: name. But the object has several attributes which include name, contact_name, contact_email and contact_phone_number.The following is what I have at the moment.
In views.py
class MerchantViewSet(GetPrefixedIDMixin, viewsets.ModelViewSet):
"""POST support for /merchants/."""
print ("in MerchantViewSet")
queryset = models.Merchant.objects.all()
serializer_class = serializers.CreateMerchantSerializer
lookup_field = "id"
# lookup_value_regex = f"{models.Merchant.id_prefix}_[a-f0-9]{32}"
lookup_value_regex = ".*"
permission_classes = [permissions.MerchantPermission]
def get_queryset(self):
"""Filter the queryset based on the full merchant name or starting with a letter."""
queryset = models.Merchant.objects.all()
search_param = self.request.query_params.get("search", None)
if search_param:
if search_param.startswith("^"):
queryset = queryset.filter(name__istartswith=search_param[1:])
else:
queryset = queryset.filter(name__icontains=search_param)
return queryset
def update(self, request, *args, **kwargs):
request.data["user"] = request.user.id
print (self.get_object().name)
print (request.data)
merchant = self.get_object()
print (response)
print (merchant.name)
for merchants in models.Merchant.objects.all():
print (merchants.id)
if (merchants.id == merchant.id):
merchants.name = request.data["name"]
merchants.save()
I've tried using
response = super(MerchantViewSet, self).update(request, *args, **kwargs)
from what I read in the DRF documentations but using this just returns error 404 when I run my test. Do I simply have to do with I did with name in my code above, with the other attributes? Or is there a more streamlined way to do this?
This is my test:
class MerchantsViewSetTest(tests.BigETestCase): # noqa
#classmethod
def setUpClass(cls): # noqa
super(MerchantsViewSetTest, cls).setUpClass()
cls.application = tests.get_application()
tests.create_group("merchant")
cls.consumer_user = tests.create_consumer()
cls.admin = tests.create_administrator()
cls.merchant_geraldine = models.Merchant.objects.create(
name="Test Account 1",
contact_name="Geraldine Groves",
contact_email="geraldine#example.com",
contact_phone_number="+35310000000",
)
cls. merchant_barbara = models.Merchant.objects.create(
name="Account 2",
contact_name="Barbara",
contact_email="barbara#example.com",
contact_phone_number="+35310000432",
)
def test_edit_merchant(self): # noqa
url = reverse("bige_transactions:merchant-detail", kwargs={'id': self.merchant_geraldine.prefixed_id})
# payload
data = {"name": "Edited"}
# Put data
resp_data = self.put(url, data, user=self.admin, status_code=200)
# Check if data was updated
url = reverse("bige_transactions:merchant-list")
# Try without authenticated user
self.get(url, status_code=401)
# Try with authenticated admin user
resp_data = self.get(url, user=self.admin, status_code=200)
print (resp_data)

django: inlineformset very slow

I have the following models:
class Recipe(models.Model):
....
class Ingredient(models.Model):
....
class RecipePosition(models.Model):
recipe = models.ForeignKey(Recipe,related_name='recipe_positions', on_delete=models.CASCADE)
ingredient = models.ForeignKey(Ingredient,related_name='ingredient_recipeposition',on_delete=models.PROTECT) ....
in my views.py i am trying to create an inlineformset so that i can edit all the Reciposition related to particular Recipe:
def recipe_ingredients_formset_update(request,slug=None):
instance = get_object_or_404(Recipe.objects.prefetch_related('recipe_positions__ingredient'), slug=slug)
RecipeIngredientsFormSet = inlineformset_factory(Recipe,RecipePosition,form=RecipePoistionForm, can_delete=True, extra=5)
if request.method == "POST":
formset = RecipeIngredientsFormSet(request.POST, request.FILES, instance=instance)
helper = RecipePositionCreateFormSetHelper()
if formset.is_valid():
formset.save()
# Do something. Should generally end with a redirect. For example:
messages.success(request, "Successfully Updated", extra_tags='alert')
return HttpResponseRedirect('')
else:
formset = RecipeIngredientsFormSet(instance=instance)
helper = RecipePositionCreateFormSetHelper()
context = {
"instance":instance,
"formset":formset,
"helper":helper,
"url":instance.get_absolute_url_recipe_update_inline_bulk_ingredients()
}
return render(request, 'recipe_recipositions_bulk_edit.html', context)
I searched on net, but not able to understand. I am using Django Debug toolbar.
If i have 56 RecipePosition items for a particular Recipe. it took me 36 seconds to load

Resources