Reputation: 45
I'm looking to show the data of the Performance model for the current user only. Right now the page shows all performance data, not only the data of the logged in user.
I'm not sure if I have the models.py setup incorrectly (does every model need to have a foreignkey related to the user?) or if there is a solution for this in the views.py file (I tried this using get_context_data but couldn't get it to work)
Any help is much appreciated!
models.py
class Adaccount(models.Model):
accountname = models.CharField(max_length=250)
def __str__(self):
return self.accountname
class Performance(models.Model):
adaccount = models.ForeignKey(Adaccount, on_delete=models.CASCADE)
date = models.DateField(auto_now_add=True)
campaign = models.CharField(max_length=500)
adset = models.CharField(max_length=500)
clicks = models.IntegerField()
impressions = models.IntegerField()
ctr = models.FloatField()
cpc = models.FloatField()
cpm = models.FloatField()
conv1 = models.IntegerField()
conv2 = models.IntegerField(blank=True, null=True)
conv3 = models.IntegerField(blank=True, null=True)
def __str__(self):
return str(self.date) + ' - ' + str(self.adaccount)
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
adaccounts = models.ForeignKey(Adaccount,null=True)
company = models.CharField(max_length=250, blank=True)
website = models.CharField(max_length=30, blank=True)
def __str__(self):
return self.company
views.py
class IndexView(LoginRequiredMixin, generic.ListView):
model = Performance
context_object_name = 'all_performance'
template_name = 'dashboard/index.html'
login_url = '/login/'
redirect_field_name = 'redirect_to'
def get_queryset(self):
return Performance.objects.all()
class HomeView(TemplateView):
model = Adaccount
template_name = 'dashboard/home.html'
HTML Template
<strong>CTR | CPC | CPM</strong><br>
{% for daily in all_performance %}
<span>{{ daily.ctr }} | {{ daily.cpc }} | {{ daily.cpm }}</span><br>
{% endfor %}
Upvotes: 0
Views: 7828
Reputation: 110
The key problem seems to be with the
def get_queryset(self):
return Performance.objects.all()
part.
You are getting all the Performance objects in the view(as you can see from objects.all()
part of the code).
You have to somehow filter the Performance with the user. You can get the current user with self.request.user
in the view.
Problem is, looking at your model, user seems to be on a related related model ( Performance -> Adaccount -> Account) which makes the operation you desire a bit complicated. This is fine as long as this is the model structure you intended to create, which gets into the architecture of your Database.
Assuming that you will not change the architecture, this is what has to happen with plain English:
Filter all the Accounts with the request.user. From those Accounts, get all the Adaccounts. Filter all the Performances from the Adaccounts.
def get_queryset(self):
user = self.request.user
adaccount_list = Account.objects.filter(user=user)\
.values_list('adaccounts', flat=True)
return Performance.objects.filter(adaccount__in=adaccount_list)
This is one approach, albeit not the most efficient but easy to visualize. Others may find better approaches - do let me know if there is any problem!
Upvotes: 2