django generic view send context to multiple templates at the same time - django

I am trying to send the listview context (book_list) in this case to more than one template at the same time.
I have tried to edit templates_names by doing this:
class BookListView(ListView):
model = Book
def get_template_names(self):
template_name=["catalog/index.html","catalog/book_list.html"]
return template_name
but book_list is still only known to catalog/book_list.html not to catalog/index.html(so the function I have added did NOT do anything).
any suggestions please?
Best regards

You just cannot :) Each view is responsible for one url and one template in will render. Actually I cannot even find and example when one would need to do what you're trying to do.
I think you have to read about template inheritance

render multiple template from a single view in django
I had same problem. If you send arguments to parents html and if your htmls are children. They can access to arguments. check the link.

Related

Why can't I inject form into HTML?

I have a form that I want to inject into a class based DetailView.
forms.py
class PastLocationForm(forms.Form):
locations = forms.ModelChoiceField(queryset=Location.objects.all().order_by('location_name'))
views.py
class PatientDetailView(DetailView):
model=Patient
form_class = PastLocationForm
Unfortunately, the form PastLocationForm doesn't appear on the HTML page after injection. I inspected the page and there was nothing.
Interestingly, if I pass PastLocationForm to a functional view and render it for another page, the form shows up! I also have other views where I make use of "form_class" for other modelForms and they function correctly.
I will switch my view to functional view if I can't find the solution but I would rather keep the class based view.
The reason might be the fact that DetailView does not handle a form_class attribute (FormViews do), you'd need to use a mixin.
Check out this answer:
Django combine DetailView and FormView

How to reuse existing admin models to display a custom Queryset?

I'm writing my first application in Django, and now that the base is covered, I try to enhance a bit the admin part to ease up my life.
I have two classes in my model:
class Puzzle(models.Model):
puzzle_pieces = models.ForeignKey(PuzzlePieces,on_delete=models.CASCADE)
class PuzzlePieces(models.Model):
puzzle_pieces = models.CharField(max_length=255, default='empty')
with admin models in place too:
class PuzzlePiecesAdmin(admin.ModelAdmin):
class PuzzleAdmin(admin.ModelAdmin):
I want to define in the PuzzlePiecesAdmin class a custom action to display (reusing the format defined in PuzzleAdmin) all the puzzles which are linked to the selected puzzle_pieces
I know how to create custom actions,
def show_related_puzzles(modeladmin, request, queryset):
I've seen on the internet different ways to filter directly within the PuzzleAdmin class,
but not how to set the queryset from the outside.
But I don't understand how to launch the display of an instance of PuzzleAdmin limited to the queryset I will define within show_related_puzzles.
Could anyone explain me how to proceed?
Thanks in advance
OK, I found the start of an answer in the following:
https://stackoverflow.com/a/1652377/12505071
the standard changelist view accepts normal queryset filter parameters as GET arguments. So you can do:
/admin/puzzles/puzzle/?puzzle_pieces__pk=21
I finally found out by trial and error how to add another filter:
/admin/puzzles/puzzle/?difficulty__id__exact=35&puzzle__pk=560
Could anybody tell me how to add a second value for the same parameter?

What is the difference between using TemplateView and ListView in Django?

In the database, I have a set of questions. I want to display every question in a collapsible item as a list. Previously I used TemplateView:
class questionmanager(TemplateView):
template_name = 'questionmanager.html'
questions = Question.objects.all()
def get_context_data(self, **kwargs):
context = ({
'questions': self.questions,
})
return context
Then, I read that using ListView is better practice to represent a list of objects. Then I changed my class to this:
class QuestionListView(ListView):
model = Question
def get_context_data(self, **kwargs):
context = super(QuestionListView, self).get_context_data(**kwargs)
return context
In the old template I used this for loop:
{% for question in questions %}
I thought I wouldn't need to use a for loop when I use ListView instead of TemplateView; but I couldn't list the items without a for loop. I found an example here, and it seems to me, the only difference is that in the for loop we use object_list ( {% for question in **object_list** %}) instead of using argument that we pass in the context.
I really don't see so much difference between using TemplateView and ListView - after spending an hour on this. I'd appreciate if someone explains why using ListView instead of TemplateView is a better practice (in this case).
Thanks in advance.
For simple use cases such as this, there isn't much difference. However, the ListView in this example is much cleaner as it can be reduced to:
class QuestionListView(ListView):
model = Question
considering you aren't putting anything in the context. TemplateView's as a base view are rather rudimentary, and provide a much smaller set of methods and attributes to work with for the more complex use cases, meaning you have to write more code in such instances. If you take a look and compare both views TemplateView and ListView here, you can see the difference more clearly. Pagination is a good example, to paginate a ListView you simply set the paginate_by attribute and modify your template accordingly.
Also note, you can change the default name object_list by setting context_object_name in the 'ListView'
The major difference is that ListView is best to list items from a database called model, while TemplateView is best to render a template with no model. Both views can be very concise with different meaning.
Below is sample of a list view in it simplest form
Class SampleListView(ListView):
model = ModelName
This will give you a context variable object_list and a template name in the form ("app_name/model_name_list.html") automatically that can be used to list all records in the database.
However, the TemplateView in its simplest form is
class SampleTemplateView(TemplateView):
template_name = 'app_name/filename.html'

Sending extra data to templates using class-based views in Django

I have recently started using Django frameworks class-based views.
Assume I have a model Book. Is it possible using class-based views, to besides sending one object of type Book, send a boolean value, which I could set in the view?
For example, I would like the view to send the dictionary context = {object: Book, green: True} to a template.
Yes, of course it's possible.
You can override get_context_data and add anything you like.
Edit
get_object gets the specific database object that the view is displaying/editing. In the default implementation, get_context_data returns a dictionary consisting of the value returned by get_object. You can call the superclass method then add your own values to the result.

Get an url pk in a generic RESTful view?

I'm trying to manage my REST API like that :
http://xxx/users/userid[0-9]+/projects/projectid[0-9]+/tasks/taskid[0-9]+/
So I can access the JSON easily in my website. But, the thing is, I defined my view classes using the REST framework generic views. For example, here is my UserDetail view :
class UserDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
But of course I don't want all my users to be displayed, I just want my user with the ID userid to be displayed. I don't really know how to do it, I tried
queryset = User.objects.filter(id=userid)
but of course userid is not defined... Any help please ?
Edit : just to clarify, here is the url that leads to this view :
url(r'^users/(?P<pku>[0-9]+)/$', views.UserDetail.as_view(
), name='user-detail'),
First of all, If you want to use class based views, you should read some more about them. They are thoroughly explained on Django's docs and you can read about the specific generics of the framework you're using on the REST framework docs too. I'm not saying that you haven't read those, just that you seem to be missing some basic concepts that are explained there.
Now, to the problem at hand, if you look at the doc's of the generic view you're extending, you can see that it represents the endpoints for a single instance, meaning that it won't act on all your model's instances (as you seem to assume).
Also, you can see that this view is built on top of a series of other classes, the more critical one being GenericAPIView. On there you can see two things:
The queryset class field in this context is meant for filtering the posible instances you can manipulate, not obtaining the specific instance described on your url.
The lookup_field is the field that defines which attribute from your model will be used for getting the actual instance. You should define this field to whatever field you're going to use on your url to identify your object (generally it's pk). It's also important to note that the url should include a keyword argument corresponding to this value.
Internally, the view will take care of calling the get_object method, which usese the lookup_field value to find the specific model, and then feed that object to the serializer and return the result back to the client.
DISCLAIMER: I've never used Django REST framework, I put this answer togheter by reading the relevants docs and based on my experience.
I guess you need this:
Resolve function (django 1.4)
Then in your view class method you can do:
temp1, args, kwargs = resolve(self.request.path)