How properly request.user.is_superuser inside function in django admin.py - python

I am learning Djnago and
I have this function inside admin.py that counts how many participants in an activity, it is working fine until, I want to know if the current user is a superuser and added request inside def set_count(self, request, obj) expecting to make a request for the user. Since I am getting an error, this means, this it's not how to do it and wrong. How to correct this? Thanks.
Below is what I want to do, evaluate the user.is_superuser if true, it will display in the list_display the link to the participants_changelist otherwise, display a plain text.
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(set_count=Count('activity_activity'))
return queryset
def set_count(self, request, obj):
counter = obj.set_count
if request.user.is_superuser:
url = (
reverse("admin:activity_announcements_participants_changelist")
+ "?"
+ urlencode({"activity__id": f"{obj.id}"})
)
return format_html('{} Paticipants', url, counter)
else:
counter = obj.set_count
return format_html('{} Paticipants', counter)
set_count.short_description = "No. of Paticipants"
Error:
TypeError at /admin/activity_announcements/activity/
ActivityAdmin.set_count() missing 1 required positional argument: 'obj'
Request Method: GET
Request URL: http://localhost:8000/admin/activity_announcements/activity/
Django Version: 4.1.5
Exception Type: TypeError
Exception Value:
ActivityAdmin.set_count() missing 1 required positional argument: 'obj'
Exception Location: /py/lib/python3.11/site-packages/django/contrib/admin/utils.py, line 280, in lookup_field
Raised during: reversion.admin.changelist_view
Python Executable: /py/bin/python
Python Version: 3.11.1
Python Path:
['/app',
'/usr/local/lib/python311.zip',
'/usr/local/lib/python3.11',
'/usr/local/lib/python3.11/lib-dynload',
'/py/lib/python3.11/site-packages',
'/py/lib/python3.11/site-packages/odf',
'/py/lib/python3.11/site-packages/odf',
'/py/lib/python3.11/site-packages/odf',
'/py/lib/python3.11/site-packages/odf',
'/py/lib/python3.11/site-packages/odf',
'/py/lib/python3.11/site-packages/odf',
'/py/lib/python3.11/site-packages/odf']
Server time: Sun, 22 Jan 2023 03:06:22 +0800

The problem is that when defining a custom field to list in the admin, you don't have access to the request. The function definition should be like this def your_field(self, obj): . In order to get the request in a field definition you can do the following:
class YourAdmin(admin.modeladmin):
def get_queryset(self, request):
self.request = request
return super().get_queryset(request)
def set_count(self, obj):
counter = obj.set_count
if self.request.user.is_superuser:
url = (
reverse(
"admin:activity_announcements_participants_changelist")
+ "?"
+ urlencode({"activity__id": f"{obj.id}"})
)
return format_html('{} Participants', url, counter)
else:
counter = obj.set_count
return format_html('{} Participants', counter)
set_count.short_description = "No. of Paticipants"

Related

TypeError: 'User' object is not iterable

I am working with a payment system in my django E commerce Project. But it shows me that user is not iterable . Here's the code
#login_required
def payment(request):
saved_address = BillingAddress.objects.get_or_create(user=request.user)[0]
if not saved_address.is_fully_filled():
messages.info(request,f'Please complete shipping address!')
return redirect('checkout')
if not request.user.profile.is_fully_filled():
messages.info(request,f'Please complete profile details!')
return redirect('profile')
store_id = '$$$$$$$$$$$$$$$'
API_key= '$$$$$$$$$$$$$$$#ssl'
mypayment = SSLCSession(sslc_is_sandbox=True, sslc_store_id=store_id, sslc_store_pass=API_key)
status_url= request.build_absolute_uri(reverse('complete'))
mypayment.set_urls(success_url=status_url, fail_url=status_url, cancel_url=status_url, ipn_url=status_url)
order_qs=Order.objects.filter(user=request.user,ordered=False)
order_items=order_qs[0].orderitems.all()
order_item_count=order_qs[0].orderitems.count()
order_total=order_qs[0].get_totals()
mypayment.set_product_integration(total_amount=Decimal(order_total), currency='BDT', product_category='Mixed', product_name=order_items, num_of_item=order_item_count, shipping_method='Courier', product_profile='None')
current_user=request.user
mypayment.set_customer_info(name=current_user.profile.full_name, email=current_user, address1=current_user.profile.address_1, address2=current_user.profile.address_1, city=current_user.profile.city, postcode=current_user.profile.zipcode, country=current_user.profile.country, phone=current_user.profile.phone)
mypayment.set_shipping_info(shipping_to=current_user.profile.full_name, address=saved_address.address, city=saved_address.city, postcode=saved_address.zipcode, country=saved_address.country)
response_data = mypayment.init_payment()
return render(request,'payment/payment.html',context={})
it work untill i wrote the last line
response_data = mypayment.init_payment()
the server shows this
TypeError at /payment/pay/
'User' object is not iterable
Request Method: GET
Request URL: http://localhost:8000/payment/pay/
Django Version: 3.2.8
Exception Type: TypeError
Exception Value:
'User' object is not iterable
Help me with this. Thanks in advance

avoid error: 'NoneType' object has no attribute in django model admin

I need to show if a client is having a related contract active or no in customized field
in django model admin
I tried to use try: but it does not work unfortunately
here the original code:
class ClientAdmin(ExportModelAdminMixin, ModelAdmin):
model = Client
menu_icon = "pick"
menu_order = 100
exclude_from_explorer = False
list_display = ["name", "is_active"]
search_fields = ["name"]
list_filter = [ClientFilter]
index_template_name = "wagtailadmin/export_csv.html"
csv_export_fields = ["name"]
def is_active(self, client: Client) -> bool:
any(site.current_contract.is_active for site in client.sites.all())
is_active.boolean = True # type: ignore
is_active.short_description = _("active confirmation") # type: ignore
I got the error:
File "/home/oladhari/reachat-v4/Reachat-v4/backend/crm/admin.py", line 61, in is_active
any(site.current_contract.is_active for site in client.sites.all())
File "/home/oladhari/reachat-v4/Reachat-v4/backend/crm/admin.py", line 61, in <genexpr>
any(site.current_contract.is_active for site in client.sites.all())
AttributeError: 'NoneType' object has no attribute 'is_active'
to resolve this error I tried to use try:
and changed the customized field to this:
def is_active(self, client: Client) -> bool:
try:
any(site.current_contract.is_active for site in client.sites.all())
except ObjectDoesNotExist:
return False
else:
return any(site.current_contract.is_active for site in client.sites.all())
but still having the same error unfortunately
please could you help me to avoid this error, thank you
Why not use a normal query for the is_active method?
So, something like:
def is_active(self, client: Client) -> bool:
return client.sites.filter(current_contract__is_active=True).exists()

Perform google search then get result save in django database

i am learning Django tutorial, could you pls advise me how to edit cod to get search result to put into database? Below are my cod and sure that the rest of cod in this tutorial i did correctly and test complete, many thanks
I have updated the code as per your request. The result on home page fail is also attached at the bottom of the question section. If you have any additional question, please ask and I will be able to share.
def __str__(self):
"""Returns a string representation of a message."""
date = timezone.localtime(self.log_date)
return f"'{self.message}' logged on {date.strftime('%A, %d %B, %Y at %X')}"
class HomeListView(ListView):
"""Renders the home page, with a list of all messages."""
model = LogMessage
def get_context_data(self, **kwargs):
context = super(HomeListView, self).get_context_data(**kwargs)
return context
def log_message(request):
form = LogMessageForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
query = form.save(commit=False)
for j in search(query, tbs='qdr:h', num=10, start=0, stop=10, pause=2.0):
message = LogMessage(log_date = datetime.now(), message =j)
message.save()
return redirect("home")
else:
return render(request, "hello/log_message.html", {"form": form})
--- HOME PAGE FAIL INFO
TypeError at /log/
quote_from_bytes() expected bytes
Request Method: POST
Request URL: http://127.0.0.1:8000/log/
Django Version: 3.1.5
Exception Type: TypeError
Exception Value:
quote_from_bytes() expected bytes
Exception Location: C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32\lib\urllib\parse.py, line 866, in quote_from_bytes
Python Executable: C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32\python.exe
Python Version: 3.8.7
Python Path:
['D:\\Apps\\07.1\\hello_django',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python38-32\\python38.zip',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python38-32\\DLLs',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python38-32\\lib',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python38-32',
'C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python38\\site-packages',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python38-32\\lib\\site-packages']
Server time: Thu, 07 Jan 2021 14:38:11 +0000
Traceback Switch to copy-and-paste view
C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py, line 47, in inner
response = get_response(request) …
▶ Local vars
C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py, line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
▶ Local vars
D:\Apps\07.1\hello_django\hello\views.py, line 34, in log_message
for j in search(query, tbs='qdr:h', num=10, start=0, stop=10, pause=2.0): …
▼ Local vars
Variable Value
form
<LogMessageForm bound=True, valid=True, fields=(message)>
query
<LogMessage: '333321212121121221' logged on Thursday, 07 January, 2021 at 14:38:11>
request
<WSGIRequest: POST '/log/'>
Try the code below:
for j in search(query, tbs='qdr:h', num=10, start=0, stop=10, pause=2.0):
message = LogMessage(log_date = datetime.now(), message =j)
message.save()

Django syndication function error

I'm trying to create a custom Django RSS feed using django syndication (actually using django wagtail feeds). I have an error which I think I've identified as stemming from a NoneType object which is returned by the get_object() function inside syndication/views.py.
`AttributeError at /feed/basic/Chups/
'NoneType' object has no attribute 'startswith'
Exception Location: /Users/technical/.virtualenvs/wagtest4-plnzODoN/lib/python3.6/site-packages/django/contrib/syndication/views.py in add_domain, line 19`
That function is called as part of class Feed() and looks like this:
def get_object(self, request, *args, **kwargs):
return None
That function is called at line 36 but fails because get_object() returns a None object.
My customisation of django wagtail feeds extends Feed in the following way:
from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import (
SyndicationFeed, rfc3339_date, Rss201rev2Feed
)
from .models import RSSFeedsSettings, RSSFeed
class BasicFeed(Feed):
# FEED TYPE
feed_type = Rss201rev2Feed
def get_object(self, request, category):
return category
try:
feed_app_settings = RSSFeedsSettings.objects.get(feed_category_name="Flex")
print(feed_app_settings)
feed_app_label = feed_app_settings.feed_app_label
feed_model_name = feed_app_settings.feed_model_name
feed_category_name = feed_app_settings.feed_category_name
use_feed_image = feed_app_settings.feed_image_in_content
except: # pragma: no cover
feed_app_settings = None
try:
feed_model = apps.get_model(app_label=feed_app_label,
model_name=feed_model_name)
except: # pragma: no cover
feed_model = None
# The RSS information that gets shown at the top of the feed.
if feed_app_settings is not None:
title = feed_app_settings.feed_title
link = feed_app_settings.feed_link
description = feed_app_settings.feed_description
author_email = feed_app_settings.feed_author_email
author_link = feed_app_settings.feed_author_link
item_description_field = feed_app_settings.feed_item_description_field
item_content_field = feed_app_settings.feed_item_content_field
def items(self, obj):
url_category = obj
categories = ContentType(app_label="blog", model="blogcategory")
category_id = categories.get_object_for_this_type(name=url_category).id
return feed_model.objects.filter(categories=category_id).order_by('-date').live()
def item_pubdate(self, item):
return datetime.combine(item.date, time())
def item_link(self, item):
return item.full_url
def item_author_name(self, item):
pass
urls.py includes this and requests seem to be reaching the function fine.
url(r'^feed/basic/(?P<category>[0-9a-zA-Z]+)/$', BasicFeed(), name='basic_feed'),
Can anyone tell me why that might be? I'm missing something about the expected functioning of this. Thanks!

Django: HTTP error 410 (Gone) with RedirectView

I get an HTTP 410 error when invoking the following Django View:
>>> views.py:
class ReopenMilestoneView(
dj_auth_mixins.LoginRequiredMixin, dj_views.RedirectView
):
pattern_name = 'bibliotheka_dashboard'
def dispatch(self, request, *args, **kwargs):
print('DISPATCH BEGIN')
instance = project_models.Milestone.objects.get(pk=kwargs['pk'])
instance.state = project_models.STATE_OPEN
instance.save()
print('DISPATCH END')
return super(ReopenMilestoneView, self).dispatch(
request, *args, **kwargs
)
def http_method_not_allowed(self, *args, **kwargs):
print('HTTP NOT ALLOWED BEGIN')
try:
return super(ReopenMilestoneView, self).http_method_not_allowed(
*args, **kwargs
)
except:
print('EXCEPTION')
print('HTTP NOT ALLOWED END')
def get_redirect_url(self, *args, **kwargs):
print('REDIRECT BEGIN')
result = super(ReopenMilestoneView, self).get_redirect_url(
*args, **kwargs
)
print('REDIRECT END, result = ' + str(result))
url = urlresolvers.reverse('bibliotheka_dashboard')
url2 = urlresolvers.reverse(self.pattern_name)
print('REDIRECT END, URL_resolved = ' + str(url))
print('REDIRECT END, pattern_name = ' + str(self.pattern_name))
print('REDIRECT END, URL_2_resolved = ' + str(url2))
return result
>>> urls.py:
...
url(
r'^milestone/dashboard/$',
project_views.MilestoneDashboard.as_view(),
name='milestone_dashboard'
),
url(
r'^milestone/(?P<pk>[\w-]+)/dashboard/$',
project_views.MilestoneDashboard.as_view(),
name='milestone_specific_dashboard'
),
...
I added prints through the three methods form "RedirectView" that are mentioned in the Django documentation as part of the regular workflow (django).
Dispatch is properly executed but, when resolving automatically the "pattern_name", "RedirectView" fails... manually resolving it, solves the problem.
DISPATCH BEGIN
DISPATCH END
REDIRECT BEGIN
REDIRECT END, result = None
REDIRECT END, URL_resolved = /
REDIRECT END, pattern_name = bibliotheka_dashboard
REDIRECT END, URL_2_resolved = /
Gone: /prj/milestone/2/reopen/
[12/Jul/2017 13:28:34] "GET /prj/milestone/2/reopen/ HTTP/1.1" 410 0
I have used "RedirectView" before but I have never got this error, any ideas? Django is not returning a lot of info back...
My URLs are defined as follows:
from django.conf.urls import url, include
from django.conf.urls import static as dj_static
from django.contrib import admin
from bibliotheka import settings as bibliotheka_settings
from documentation.views import project as project_views
urlpatterns = [
url(
r'^$',
project_views.MilestoneDashboard.as_view(),
name='bibliotheka_dashboard'
),
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('accounts.urls')),
url(r'^accounts/', include('allauth.urls')),
url(r'^prj/', include('documentation.urls.project')),
url(r'^dox/', include('documentation.urls.documents')),
url(r'^dox/', include('documentation.urls.discrepancies')),
]
if bibliotheka_settings.DEBUG:
urlpatterns += dj_static.static(
bibliotheka_settings.MEDIA_URL,
document_root=bibliotheka_settings.MEDIA_ROOT
)
I am trying to redirect to "/" with the problematic views.
Django is failing to reverse milestone_dashboard. In Django <= 1.11, it silences the NoReverseMatch, and returns a 410 response.
This behaviour has been changed in Django 2.0 (see ticket 26911), so Django will no longer silence the exception.
When you use pattern_name, Django tries to reverse with the same args and kwargs. You do not want this, as you are redirecting from a url containing the pk to a url that does not have any arguments.
You can set url with reverse_lazy:
from django.urls import reverse_lazy
class ReopenMilestoneView(RedirectView):
url = reverse_lazy('bibliotheka_dashboard')

Categories