In my AbstractBaseUser
I have 6 BooleanField
values, each with different verbose_name.
Now I would like to reference this verbose name somehow in my template.
I have tried:
{{ obj.verbose_name }}
but it doesn’t work.
Also tried creating a template tag file on which I was getting 'str' object has no attribute '_meta'
error. I will post my code bellow for reference:
# Own custom user model
class Account(AbstractBaseUser):
username = models.CharField(max_length=30, unique=True)
guardianSource = models.BooleanField(verbose_name='The Guardian',default=True)
bbcSource = models.BooleanField(verbose_name="BBC", default=False)
independentSource = models.BooleanField(verbose_name="The Independent", default=False)
categoryCoronaVirus = models.BooleanField(verbose_name="Coronavirus", default=False)
categoryPolitics = models.BooleanField(verbose_name="politics", default=False)
categorySport = models.BooleanField(verbose_name="sport", default=False)
The boolean values represent users preference for source of news, and categories of news.
My HTML file contains:
{% for source in checkSources %} <<checkSources is a list with 3 booleanSources for each user>>
{% if source == True %}
{% for category in checkCategories %} <<checkCategories is a list with 3 booleanCategies for each user>>
{% if category == True %}
<< HERE I NEED TO COMPARE article.soure AND article.category TO EACH OF THE boolean values verbose_name for the user, article.source and article.category is a string value>>
<div class="card mb-4">
<img class="card-img-top" src="{{ article.image }}" alt="Card image cap">
<div class="card-body">
<h2 class="card-title">{{ article.headline }}</h2>
<p class="card-text">{{ article.body }}</p>
<a href="{{ article.url }}" target="_blank" class="btn btn-primary">Read More →</a>
</div>
<div class="card-footer text-muted">
Posted on {{ article.date | date:"F d Y" }} by
{% if article.source == "BBC" %}
<a href="https://www.bbc.co.uk" target= _blank>BBC News UK</a>
{% elif article.source == "The Guardian" %}
<a href="https://www.theguardian.com" target= _blank>The Guardian</a>
{% elif article.source == "The Independent" %}
<a href="https://www.independent.co.uk" target= _blank>The Independent</a>
{% else %}
<a href="">Unknown Source</a>
{% endif %}
Category: <b>{{ article.category | title }}</b>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
I need somehow to compare if an article source equals users picked (by Boolean) sources and same for categories.
This is why I need to reference the verbose of each boolean field somehow.
Thanks in advance!
In your template, you reference an attribute named “article.source”. Where does that come from?
Regarding the use of your boolean fields in your template, it’s actually easier than what you’re trying to do. Assuming the proper boolean values are set in the model, you should be able to do something like this:
<div class="card-footer text-muted">
Posted on {{ article.date | date:"F d Y" }} by
{% if bbcSource %}
<a href="https://www.bbc.co.uk" target= _blank>BBC News UK</a>
{% elif guardianSource %}
<a href="https://www.theguardian.com" target= _blank>The Guardian</a>
{% elif independentSource %}
<a href="https://www.independent.co.uk" target= _blank>The Independent</a>
{% else %}
<a href="">Unknown Source</a>
{% endif %}
Category: <b>{{ article.category | title }}</b>
</div>
Sorry, forgot to reference my other model:
class Article(models.Model):
headline = models.CharField(max_length=200)
body = models.CharField(max_length=5000)
url = models.CharField(max_length=200)
image = models.CharField(max_length=200)
category = models.CharField(max_length=100)
source = models.CharField(max_length=50, default="Unknown Source")
favourite = models.BooleanField(default=False)
date = models.DateTimeField()
I am not aiming to use the boolean values (true or false) I can do that. The thing is, article has source and category as a CharField
which I somehow need to compare to each BooleanField
from user. Only way to do it (that I can think of it) is to assign some string value to each boolean.
On registering user can pick up to 3 sources and 3 categories. All those 6 choices are boolean values. I need to print an article depending on users choices.
It seems to me that this is work that should be done in your view and not in the templates. As a general principle, you want to keep your “business logic” out of your templates.
Your view should identify which Articles to pass to the template, not to retrieve all Articles and then filter them out from the template.
What’s your view look like that renders this template?
Good to know that, I just started learning django a couple of weeks ago .
This is my home view:
### HOME VIEW ###
def home(request):
context = {}
accounts = Account.objects.filter(username=request.user).first()
articles = Article.objects.all()
context['accounts'] = accounts
context['articles'] = articles
# Get the user preferred sources and categories
useGuardian = accounts.guardianSource
useBBC = accounts.bbcSource
useIndependent = accounts.independentSource
setCoronaVirus = accounts.categoryCoronaVirus
setPolitics = accounts.categoryPolitics
setSport = accounts.categorySport
sources2 = [useGuardian, useBBC, useIndependent]
categories2 = [setCoronaVirus, setPolitics, setSport]
context['checkSources'] = sources2
context['checkCategories'] = categories2
# Scrape
scraper = Scraper(sources, categories)
# checkRecent can take a "force-scrape" parameter to enforce the scraper to always scrape
# if scraper.checkRecent("force-scrape"):
if scraper.checkRecent("force-scrape"):
print("Force Scraping")
else:
scraper.search()
return render(request, 'home.html', context)
accounts = Account.objects.filter(username=request.user).first()
request.user is the User object, not just the username. No need to perform the query.
This is where you want to create your filter for the articles to be displayed:
articles = Article.objects.all()
(While I probably wouldn’t have designed these models this way, there still appears to be more going on than what you’ve provided, so I’m going to assume there’s a reason for how they’re designed.)
I’d be tempted to build a query like this:
selection_list = ['Unknown Source']
if request.user.guardianSource: selection_list.append('The Guardian')
if request.user.bbcSource: selection_list.append('BBS')
if request.user.independentSource: selection_list.append('The Independent')
articles = Article.objects.filter(source__in=selection_list)
I recently was advised to do it in this specific way since it will only be prototype at the moment. Today I realized that it is not a good implementation, however, the prototype is due to Tuesday and I don’t really want to redesign again the account app.
So in my understanding I would do something like this:
selection_list = ['Unknown Source']
if request.user.guardianSource: selection_list.append('The Guardian')
if request.user.bbcSource: selection_list.append('BBS')
if request.user.independentSource: selection_list.append('The Independent')
if request.user.categoryCoronaVirus: selection_list.append("Coronavirus")
.... same for other two categories
articles = Article.objects.filter(source__in=selection_list)
Then in my template view can I do the following:
## pseudo code:
for article in article_list:
for source in source_list:
for category in category_list:
print(Article)
Thank you so much for you help so far, really appreciate that!
EDIT: actually that last bit that I wrote makes no sense, I could do
for each article in article_list print article.
Sorry, my brain is just burned, spent 3 hours on trying to get the verbose_name
You’re close, except that categories and sources are different fields in Article.
That means that it should be something more like:
source_selections = ['Unknown Source']
if request.user.guardianSource: source_selections.append('The Guardian')
if request.user.bbcSource: source_selections.append('BBS')
if request.user.independentSource: source_selections.append('The Independent')
category_selections = []
if request.user.categoryCoronaVirus: category_selections.append("Coronavirus")
... repeated two more times
articles = Article.objects.filter(source__in=source_selections, category__in=category_selections)
Note: You’ll need to ensure that you’re properly handling the case where a user doesn’t select a category.)
Amazing! Yes, on submitting the form users are not allow to submit without at least one source and one category.