Access Django model name from admin url pattern - python

Given an url like:
http://127.0.0.1:8000/admin/foo/bar/
How can I access the bar variable from the request, using the request.resolver_match.kwargs ?
What kwarg does the admin give too bar?
Tried different keys like class, content_type, slug, model, but none of them work.
EDIT:
It seems the correct kwarg is model_name which is returning None, however. I managed to extract the model name using:
request.resolver_match.url_name.split('_')[1]
But wondering if there is a more direct way.

That should be just the app label. If you're hitting that url, then you are in the ModelAdminclass. To access the app label (foo in the question example) from ModelAdmin you can do self.model._meta.app_label, so you shouldn't need to go through the request.
You can access the model (bar in question the example) in ModelAdmin with self.model.
The model name won't be directly in the request object unless you put it there. You can get it from the request.path.strip('/').split('/')[-1] or from request.resolver_match.url_name.split('_')[1]

Related

Is it necessary to have a model and inheritance in class based views?

class home(ListView):
template_name='blog/base.html'
This doesn't work and gives this error --
ImproperlyConfigured at /
home is missing a QuerySet. Define home.model, home.queryset, or override
home.get_queryset().
but when I create a model with no data
class home(ListView):
model = Post
template_name='blog/base.html'
This works perfectly fine
-> In same way when I don't inherit ListView
class home():
model = Post
template_name='blog/base.html'
It gives the following error in urls.py
from django.urls import path,include
from . import views
from .views import home
urlpatterns = [
# path('',views.home,name='blog-home'),
path('',home.as_view(),name='blog-home')
]
AttributeError: type object 'home' has no attribute 'as_view'
I don't have any idea about both of these
Yes, passing the modal is important in django generic views because ListView inherits from BaseListView which is again inherits from MultipleObjectMixin. The MultipleObjectMixin makes it mandatory to pass modal in the query_set.
See Django code of MultipleObjectMixin to get a better understanding.
I agree to the answer by "Vivek Singh".
But apart from that, your second question where you do not inherit ListView you get the error in urls is because, for as_view() to work, you have to inherit some sort of View class. Such as ListView, DetailView (which come under Generic Views) or just simply View.
In my understanding your questions is rather aiming at "the reason why" and not so much for code:
Django class based ListView/DetailedView etc. are made with the purpose to simplify the typical web pages with a list and details of e.g. products which are stored in a database table (=django model). Thus reducing coding effort. Therefore a model is required that contains the items to list and to detail. If the model given is empty can only be found at runtime when the list page is called an the query is executed - you then just get a web page with an empty product list.
Also inheriting from ListView and defining the model only makes sense if on the rendered html template you use the (automatically) filled context to display the model list.
roughly what happens when you call YourListView.as_view():
-> request
-> dispatch request via urls.py
-> YourListView.as_view()
-> instantiate YourListView with model
-> fill context with query result of the model (!!!)
-> render html template with context
-> return response
(and this is only a small basic example of what ListView can simplify for you)
If you dont need a list/details of a model, there is obviously no need to inherit from those standard views. Then you have simply different needs.
You are free to define your own ClassBased Views, without that functionality provided by ListView etc.
Hope that helps you.

How to get querystring value while loading the class in django

I need to get the value from querystring which is passing through ajax source. I have class named as xxxx. While loading the class i want to get the value from that querystring. I can able to get the value inside the method using request.GET.get('xxxx') syntax. But i want to get the value while loading the class.
sAjaxSource: "/api/helpdesk/?format=json&xxxx=10",
I have mentioned the ajax url above.
My api.py file:
class helpdesk(ModelResource):
class Meta:
""" Here i would like to get the xxxx value"""
Inside the method i can easily get it using request.GET.get("xxxx").Plz anyone help me to do this.Thanks in advance.
I don't think that's possible.
django-tastypie and similar packages for creating REST APIs leverage the functionality Class-Based Views (CBV) allow, which means that each of those URLs have been assigned the instance method they will use as its view when a request is made to such URL which, in turn, means that the class has been initialized before the request object is passed to any methods of the class.
At that point, the class does not know anything about your requests.

How to request URL of previous page visited and store parts of it as a ForeignKey?

I have a django application that has an architecture:
Myapp.com/< uniquepageURL>
For posting new things to the page:
Myapp.com/< uniquepageURL>/post
For commenting on a specific post on a page
Myapp.com/< uniquepageURL>/comment< ID# of the post>
For example, if you are commenting on the post that is stored in the database with an ID of 22 then the URL should look like:
Myapp.com/< uniquepageURL>/comment22
This is how I’ve decided to map my urls. Is there a better/simpler way to do it? The < uniquepageURL> is also the ForeignKey of the post object in my models. What I am having trouble with is figuring out how to use the request function in django to look at what the url was so as to gain information from it, namely for posts which uniquepage it is from so I can save the value into the foreignkey field and for comments which post ID it is a comment of. What would the views for each look like?
Here is my urls.py.
For posts:
url(r'^(?P<uniquepageURL>[a-zA-Z0-9_.-]*)/post/$', views.post, name='post')
for comments:
url(r'^(?P<uniquepageURL>[a-zA-Z0-9_./-]*)/comment(?P<post.pk>[0-9]*)/$', views.comment, name='comment')name='comment')ts:
I think the post.pk part is wrong since it returns an error. But I can fix that myself hopefully if I can figure out how to get the post section working at least.
Be aware that the ?P<uniquepageURL> syntax indicates a named group; Django will attempt to match that name to arguments in the view function (see https://docs.djangoproject.com/en/1.7/topics/http/urls/#named-groups).
So, to get that value passed to your view function, simply include a parameter uniquepageURL. Note that means post.pk won't work as a name; consider post_id as an alternative. (Though I supposed you could use a **kwargs construct and get at the value with kwargs['post.pk']).
That said, if you do need other information from the request URL, I think the value you are looking for is request.path (which presumes your signature is def comment(request, uniquepageURL, post_id) or similar.

Django autogenerate POST data dict for arbitrary admin form

I would like to autogenerate a dictionary of data to POST to a django admin change form, as if the current object is not changing. Basically simulate the POST request that would happen if you do a GET on the change page from the admin, and then click Save. This should take into account which fields are editable on that particular change form, and also be able to handle InlineAdmins.
def auto_generate_changeform_data(object):
data = ???
return data
For example, in line 302 of the django admin testcases they manually create the POST data dictionary, but this is something that should be possible to autogenerate, right?
I would then use this function in a testcase where I want to test what happens when I change one particular field on that model, or even one of the inlines.
#some testcase
some_object = SomeModel.objects.get(...)
url = reverse("admin:appname_modelname_change", args=[some_object.id])
data = auto_generate_changeform_data(some_object)
data['some_field'] = 'new value' #this is the only change I want to make
response = self.client.post(url, data)
I could do all of this in a more unit-y fashion by using the methods on the ModelAdmin class instead of going through a POST request to the client, but I want a functional test not a unit test in this case. I actually do want to simulate the full POST to the url.
How can I get this data dictionary, particularly the part about inline formsets?
I've done this before by simply doing the GET request with the test client and then using BeautifulSoup to scrape out all the input and select elements.
It's not completely straightforward because of the different ways those elements represent their values, but here is some code that should work.

how do you style a form already inside django

I'm using django-registration. I'd like to update the AuthenticationForm in 'django.contrib.auth.forms'. Specifically, I would like to pass the 'attrs' dict to add a few attributes. How do I update a form that comes with django?
You can use the views that come with auth and override the form parameter with your own form:
django.contrib.auth.views.login(request[, template_name, redirect_field_name, authentication_form])
More info here.
The standard way is to subclass AuthenticationForm, change the attrs in constructor, pass the form to login view and write a new entry in urls.py.
This is a nightmare: in order to add html attribute to a field it is necessary to use python subclassing, to know how exactly django's form metaclass work (self.fields['field'].widget.attrs, not just self.field.widget.attrs), to know regexes (for urls.py), to know how django's urls.py work (should you put the overriding line before of after include('django.contrib.auth.urls')?) and to know where is the auth form and auth view imported from.
And now the "commercial break": just use http://pypi.python.org/pypi/django-widget-tweaks for your task ;)

Categories