How to add data to context object in DetailView? - django

I need to write a DetailView in Django. I achieved this functionality. However, I need to add some more data along with the context object. How will I achieve this.
My generic view is:
class AppDetailsView(generic.DetailView):
model = Application
template_name = 'appstore/pages/app.html'
context_object_name = 'app'
I need to add one more variable to the context object:
response = list_categories(storeId)

How about using get_context_data
class AppDetailsView(generic.DetailView):
model = Application
def get_context_data(self, **kwargs):
context = super(AppDetailsView, self).get_context_data(**kwargs)
context['categories'] = list_categories(storeId)
return context

Related

Current user variable in ListView class

I want to execute a database query using the currently logged in user within a ListView class. Then after that I want to put those results into the extra_context variable so I can access them on the html page. After looking on different websites I found this piece of code:
class className(LoginRequiredMixin, ListView):
context_object_name = 'contextName'
template_name = 'app_list.html'
def get_queryset(self):
return Userproject.objects.filter(user=self.request.user)
How can I put the current user into a variable, that I can use later on in a database query so I can use it like this (I dont want to use the current user variable in the HTML. I want to access that variable within the class itself):
class className(LoginRequiredMixin, ListView):
def get_queryset(self):
return User.objects.filter(user=self.request.user)
user = THIS IS WHERE I WANT THE CURRENT USER VALUE
context = {
'friends': friends.Objects.filter(friendId = user.id)
}
model = User
template_name = friends/friend.html
context_object_name = 'friends'
you can override the get context data method.
def get_context_data(self, **kwargs):
context = super(ClassName, self).get_context_data(**kwargs)
context['user_obj'] = Userproject.objects.filter(user=self.request.user)
return context
you can avail user_obj in templates

Filter model based of context data using django filter

I have a detail view of a model that I want to display together with a list of products and Im trying to integrate django_filter within this view.
Error Message
TypeError at /collections/christmas/?category=mens,
get context data takes exactly 2 arguments (1 given)
Filter
class ProductFilter(django_filters.FilterSet):
class Meta:
model = Product
fields = ['categories']
Detail View
class collection_detail(DetailView):
model = Collection
def get_context_data(self, request, **kwargs):
context = super(collection_detail, self).get_context_data(**kwargs)
context['collection_list'] = ProductFilter(request.GET, queryset=Product.objects.filter(collection=self.object.id).filter(structure='parent'))
return context
How i intend it to work
The category filter is pre-defined in a list of links, so when the user clicks on a collection related to a specific category the url of the detail view would look like /collections/christmas/?category=mens .
What am I specifically doing wrong here? Is it possible to even do this?
You're missing *args in your overridden method.
class collection_detail(DetailView):
model = Collection
def get_context_data(self, *args, **kwargs):
context = super(collection_detail, self).get_context_data(*args, **kwargs)
context['collection_list'] = ProductFilter(self.request.GET, queryset=Product.objects.filter(collection=self.object.id).filter(structure='parent'))
return context

How do I get django url parameters from a view mixin?

Exactly what the title says. I have a mixin that needs to pull in the id of a model field in order to be useful. I assume the easy way to do that would be to pull it from the URL.
class StatsMixin(ContextMixin):
def get_stats_list(self, **kwargs):
# the ??? is the problem.
return Stats.objects.filter(id=???).select_related('url')
def get_context_data(self, **kwargs):
kwargs['stats'] = self.get_stats_list()[0]
print kwargs
return super(StatsMixin, self).get_context_data(**kwargs)
Here's the view implementation for reference.
class ResourceDetail(generic.DetailView, StatsMixin):
model = Submissions
template_name = 'url_list.html'
queryset = Rating.objects.all()
queryset = queryset.select_related('url')
You can access URL parameters in Django by using, self.args and self.kwargs.

Django - Passing the model name to a view from url

How would I make it so I could pass the model name as a parameter in the url to a view? I would like to reuse this view and just pass the model name through to show a list of whatever model the parameter was.
Heres what I have so far
View
class ModelListView(ListView,objects):
model = objects
template_name = "model_list.html"
def get_context_data(self,**kwargs):
context = super(ModelListView, self).get_context_data(**kwargs)
context['listobjects'] = model.objects.all()
return context
URLS
url(r'^musicpack', MusicPackListView.as_view(), name='musicpack-list', objects = 'MusicPack'),
url(r'^instruments', MusicPackListView.as_view(), name='instrument-list', objects = 'Instrument'),
ANSWERED
Hey thanks for the answer
I've gone with the following and it seems to work.
View
class ModelListView(ListView):
template_name = "model_list.html"
def get_context_data(self,**kwargs):
context = super(ModelListView, self).get_context_data(**kwargs)
return context
URLS
#models
from inventory.views import MusicPack
from inventory.views import Instrument
#views
from inventory.views import ModelListView
url(r'^musicpacks', ModelListView.as_view(model = MusicPack,), name='musicpack-list'),
url(r'^instruments', ModelListView.as_view(model = Instrument,), name='instrument-list'),
I would pass perameter from urls to views like this:
VIEWS:
class ModelListView(ListView):
model = None
model_name= ''
object = None
template_name = "model_list.html"
def get_context_data(self,**kwargs):
context = super(ModelListView, self).get_context_data(**kwargs)
context['listobjects'] = model.objects.all()
return context
URLS:
url(r'^musicpack', ModelListView.as_view( model= MusicPackList,model_name= 'music_pack_list' object = 'MusicPack')),
url(r'^instruments', ModelListView.as_view( model=InstrumentPackList,model_name= 'instrument_pack_list', object= 'InstrumentPack'))

How to render multiple objects using class based views

I try to render multiple objects using class based views but I get an error.
Here are my codes:
class AssociatedList(WizardRequiredMixin, TemplateView):
template_name = "profile/associated_accounts.html"
def get_context_data(self, **kwargs):
context = super(AssociatedList, self).get_context_data(**context)
all_envelopes = Envelope.objects.filter(
user=request.user).exclude_unallocate()
free_limit = account_limit(request, 15, all_envelopes)
facebook = FacebookProfile.user_profiles(request.user)
google = GoogleProfile.user_profiles(request.user)
twitter = TwitterProfile.user_profiles(request.user)
context.update = ({
'facebook': facebook,
'google': google,
'twitter': twitter,
'free_limit': free_limit,
})
return context
Error:
local variable 'context' referenced before assignment
I've always overridden get_context_data by calling super at the beginning of the function and then appending context -
def get_context_data(self, *args, **kwargs):
context = super(AssociatedList, self).get_context_data(*args, **kwargs)
all_envelopes = Envelope.objects.filter(
user=self.request.user).exclude_unallocate()
free_limit = account_limit(self.request, 15, all_envelopes),
facebook = FacebookProfile.user_profiles(self.request.user),
google = GoogleProfile.user_profiles(self.request.user),
twitter = TwitterProfile.user_profiles(self.request.user),
context.update({
'facebook': facebook,
'google': google,
'twitter': twitter,
'free_limit': free_limit,
})
return context
This is the pattern used in the docs here.
UPDATE
The error you've just added suggests an error with your class. It sounds like you need to define either a queryset attribute or a model attribute.
The ListView class that you're inheriting from requires you to either define the model that the View returns (ie YourModel.objects.all()). Or else the specific queryset to be returned (eg YourModel.objects.filter(your_field=some_variable)).
Because this is a ListView, you need to tell it what you are going to list with either a model or queryset. You don't want to use a ListView in this case since you are overriding get_context_data so you should probably use a TemplateView or something similar.
Try something like this:
class AssociatedList(WizardRequiredMixin, ListView):
template_name = "profile/associated_accounts.html"
model = Envelope
def get_queryset(self):
return Envelope.objects.filter(user=self.request.user).exclude_unallocate()
def get_context_data(self, **kwargs):
context = super(AssociatedList, self).get_context_data(**kwargs)
context.update({
'facebook': FacebookProfile.user_profiles(self.request.user),
'google': GoogleProfile.user_profiles(self.request.user),
'twitter': TwitterProfile.user_profiles(self.request.user),
'free_limit': account_limit(self.request, 15, context['envelope_list']),
})
return context
You don't need model having queryset, but it is good practice to define it.
In template use object_list or envelope_list instead of all_envelopes and you should be good to go.
P.S. http://ccbv.co.uk/ good source of knowledge about CBV.