django-shop
django-shop copied to clipboard
Reverse admin url of Customer Model
how can I get the reverse admin URL of the customer model?
I tried:
reverse('admin:shop_customer_changelist')
but could not get it.
could anyone help me, please?
It's admin:shop_customerproxy_changelist
Small hint to find out yourself:
- Go to the admin page you are looking for.
- Copy the URL without the site part, here
/en/admin/shop/customerproxy/
. - Run
./manage.py shell
- Use that URL in function
resolve
. - Recheck with
reverse
if the URL is the same.
>>> from django.urls import *
>>> resolve('/en/admin/shop/customerproxy/')
ResolverMatch(func=django.contrib.admin.options.changelist_view, args=(), kwargs={}, url_name=shop_customerproxy_changelist, app_names=['admin'], namespaces=['admin'])
>>> reverse('admin:shop_customerproxy_changelist')
'/en/admin/shop/customerproxy/'
I really appreciated your comprehensive answer. I could get the URL using your solution. I wanted to ask your idea about getting this URL dynamically using the Customer model. I have this in my admin.py:
@admin.register(AnswerSheetModel)
class AnswerSheetModelAdmin(admin.ModelAdmin):
list_display = ('get_customer')
@admin_link('customer', 'Customer')
def get_customer(self, customer):
return customer
and here is my decorator:
def admin_change_url(obj):
app_label = obj._meta.app_label
model_name = obj._meta.model.__name__.lower()
return reverse('admin:{}_{}_change'.format(
app_label, model_name
), args=(obj.pk,))
def admin_link(attr, short_description, empty_description="-"):
def wrap(func):
def field_func(self, obj):
related_obj = getattr(obj, attr)
if related_obj is None:
return empty_description
url = admin_change_url(related_obj)
return format_html(
'<a href="{}">{}</a>',
url,
func(self, related_obj)
)
field_func.short_description = short_description
field_func.allow_tags = True
return field_func
return wrap
It gives the admin URL for change model page.
Is adding an if
statement for determining the Customer model only solution? like this:
def admin_change_url(obj):
app_label = obj._meta.app_label
model_name = obj._meta.model.__name__.lower()
if model_name == 'customer':
return reverse('admin:shop_customerproxy_change', args=(obj.pk,))
return reverse('admin:{}_{}_change'.format(
app_label, model_name
), args=(obj.pk,))
Is there any better solution?
What shall AnswerSheetModelAdmin
do?
BTW, if you are using a tuple in list_display = ('get_customer')
, don't forget the comma – you did. It is better to use lists anyway.
Here is my AnswerSheetModel:
class AnswerSheetModel(BaseModel):
questionnaire = models.ForeignKey(QuestionnaireModel, on_delete=models.DO_NOTHING, related_name='answers')
customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING, null=False, blank=False)
ip = models.CharField(null=True, max_length=20)
def __str__(self):
return self.questionnaire.name + ': ' + self.customer.first_name + ' ' + self.customer.last_name
BTW, if you are using a tuple in list_display = ('get_customer'), don't forget the comma – you did.
thank you very much, yes I have trailing comma, I deleted it Here for simplicity :-)
It's
admin:shop_customerproxy_changelist
Small hint to find out yourself:
- Go to the admin page you are looking for.
- Copy the URL without the site part, here
/en/admin/shop/customerproxy/
.- Run
./manage.py shell
- Use that URL in function
resolve
.- Recheck with
reverse
if the URL is the same.>>> from django.urls import * >>> resolve('/en/admin/shop/customerproxy/') ResolverMatch(func=django.contrib.admin.options.changelist_view, args=(), kwargs={}, url_name=shop_customerproxy_changelist, app_names=['admin'], namespaces=['admin']) >>> reverse('admin:shop_customerproxy_changelist') '/en/admin/shop/customerproxy/'
Regarding that URL, I have problems accessing the following addresses:
http://localhost:8000/es/admin/shop/customerproxy/4/change/ or http://localhost:8000/es/admin/shop/customerproxy/add/
I have the following error:
TypeError at /es/admin/shop/customerproxy/4/change/
has_add_permission() takes 2 positional arguments but 3 were given
Request Method: GET
Request URL: http://localhost:8000/es/admin/shop/customerproxy/4/change/
Django Version: 3.0.7
Exception Type: TypeError
Exception Value:
has_add_permission() takes 2 positional arguments but 3 were given
Exception Location: /home/ikki/.virtualenvs/vmedexample/lib/python3.6/site-packages/django/contrib/admin/options.py in get_inline_instances, line 596
Python Executable: /home/ikki/.virtualenvs/vmedexample/bin/python
Python Version: 3.6.0
Python Path:
['/home/ikki/Desarrollo/implementacion/medexample',
'/home/ikki/Desarrollo/implementacion/medexample',
'/home/ikki/Desarrollo/ide/pycharm-2020.1.1/plugins/python/helpers/pycharm_display',
'/home/ikki/.pyenv/versions/3.6.0/lib/python36.zip',
'/home/ikki/.pyenv/versions/3.6.0/lib/python3.6',
'/home/ikki/.pyenv/versions/3.6.0/lib/python3.6/lib-dynload',
'/home/ikki/.virtualenvs/vmedexample/lib/python3.6/site-packages',
'/home/ikki/Desarrollo/ide/pycharm-2020.1.1/plugins/python/helpers/pycharm_matplotlib_backend']
Server time: Lun, 15 Jun 2020 16:33:36 +0000
I have made from the installation cookiecutter-django-shop
by default with all the sample data.
what is the solution?