Django {% regroup %} produces duplicate groups - django

I've defined the following models:
class Topic(models.Model):
class Meta:
ordering = [
'title']
objects = models.Manager()
highlighted = HighlightedTopicManager()
highlight = models.BooleanField(
default=False,
help_text='Show this topic on the home page?',
db_index=True)
highlight_order = models.PositiveSmallIntegerField(
default=0,
help_text='In what order do you want this to be added on the home page?'\
' Leave blank for alphabetic order.',
db_index=True)
title = models.CharField(
max_length=2048,
db_index=True)
slug = models.SlugField(
max_length=128,
db_index=True)
excerpt = models.TextField(
null=True,
blank=True)
description = models.TextField()
def _get_content(self):
if self.excerpt:
return self.excerpt
return self.description
content = property(_get_content)
#models.permalink
def get_absolute_url(self):
return ('academic_projects_topic_detail', (), {'slug': self.slug})
def __unicode__(self):
return self.title
class Project(models.Model):
class Meta:
ordering = [
'topic',
'modified',
'created']
objects = models.Manager()
highlighted = HighlightedProjectManager()
highlight = models.BooleanField(
help_text='Highlight this in the projects\' main page?'\
' Only the most recently modified one will be displayed.')
redirect_to = models.URLField(
blank=True,
null=True,
help_text='Use this for old or extenal projects.')
short_title = models.CharField(
max_length=1024,
db_index=True)
slug = models.SlugField(
max_length=128,
db_index=True)
title = models.CharField(
max_length=2048,
db_index=True)
created = models.DateTimeField(
auto_now_add=True)
modified = models.DateTimeField(
auto_now=True)
excerpt = models.CharField(
max_length=1024,
null=True,
blank=True,
help_text='Concise description to show in the listing page.')
description = models.TextField(
null=True,
blank=True,
help_text='This content will be rendered right after the title.')
downloads = models.ManyToManyField(
Download,
null=True,
blank=True,
help_text='Downloadable files')
footer = models.TextField(
null=True,
blank=True,
help_text='This content will be rendered at the bottom of the page.')
people = models.ManyToManyField(
Person,
help_text='People involved in this project.',
related_name='projects')
organizations = models.ManyToManyField(
Organization,
help_text='Organizations involved other than the lab.',
blank=True,
null=True,
related_name='projects')
publications = models.ManyToManyField(
Publication,
blank=True,
null=True)
topic = models.ForeignKey(
Topic,
verbose_name=_('Main topic'),
help_text='This is the main topic.',
related_name='projects')
sponsors = models.ManyToManyField(
Sponsor,
blank=True,
null=True,
help_text='sponsored_projects')
related_topics = models.ManyToManyField(
Topic,
null=True,
blank=True,
help_text='Optional related topics.',
related_name='secondary_projects')
def __unicode__(self):
return self.short_title
#models.permalink
def get_absolute_url(self):
return ('academic_projects_project_detail', (), {'slug': self.slug})
And use the following template to produce this page (http://seclab.cs.ucsb.edu/academic/projects/):
{% extends "academic/project_base.html" %}
{% block content_title %}Projects{% endblock %}
{% block title %}Projects - {{block.super}}{% endblock %}
{% block content %}
{% regroup object_list|dictsort:"topic" by topic as topic_list %}
{% for topic in topic_list %}
<h2 id="{{ topic.grouper.slug }}">{{ topic.grouper }} #</h2>
{% for project in topic.list %}
<h3>{{ project }}</h3>
<p>{{ project.title }}</p>
{% endfor %}
{% endfor %}
{% endblock %}
The view behind this is a generic one, and invoked as:
url(r'^$',
cache_page(ListView.as_view(
queryset=Project.objects.order_by('topic'),
template_name='academic/project_list.html')),
name='academic_projects_project_list'),
So, Projects are already sorted by Topic. Unfortunately, this code yields to duplicate gorups and, sometimes, the groups change at each refresh (or, at least, they change when I reboot the server).
Any idea of why is this happening? The entire code, besides templates', resides here: https://bitbucket.org/phretor/django-academic/src/

The dictsort filter is only for lists of dicts, you don't need it at all here. Your template should read
{% regroup object_list by topic as topic_list %}

Related

Django form selection box 'jammed' as active so cant make selections

USERS can Upvote or Downvote Posts/Projects posted by Other Users:
screenshot of 'jammed' active dropdown selection box
THIS CODE DIRECTLY BELOW is the models.py that contains the Project class (model) with the vote_total and vote_ratio fields.
It also contains the Review class (model) which is the basis for the ReviewForm in forms.py (code included later)
class Project(models.Model):
owner = models.ForeignKey(Profile, null=True, blank=True, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
featured_image = models.ImageField(null=True, blank=True, default="default.jpg")
demo_link = models.CharField(max_length=2000, null=True, blank=True)
source_link = models.CharField(max_length=2000, null=True, blank=True)
tags = models.ManyToManyField('Tag', blank=True)
vote_total = models.IntegerField(default=0, null=True, blank=True)
vote_ratio = models.IntegerField(default=0, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
def __str__(self):
return self.title
class Meta:
# ordering = ['-created']
ordering = ['-vote_ratio', 'vote_total', 'title']
AND here is the Review class (model)
class Review(models.Model):
VOTE_TYPE = (
('up', 'Up Vote'),
('down', 'Down Vote'),
)
owner = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
body = models.TextField(null=True, blank=True)
value = models.CharField(max_length=200, choices=VOTE_TYPE)
created = models.DateTimeField(auto_now_add=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
class Meta:
unique_together = [['owner', 'project']]
def __str__(self):
return self.value
Here is the ReviewForm from the forms.py
class ReviewForm(ModelForm):
class Meta:
model = Review
fields = ['value', 'body']
labels = {
'value': 'Place your vote',
'body': 'Add a comment with your vote'
}
def __init__(self, *args, **kwargs):
super(ReviewForm, self).__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs.update({'class': 'input'})
Here is the html template where the form is located
<div class="comments">
<h3 class="singleProject__subtitle">Comments</h3>
<h5 class="project--rating">
{{project.vote_ratio}}% Postitive ({{project.vote_total}} Vote{{project.vote_total|pluralize:"s"}})
</h5>
{% if request.user.profile.id in project.reviewers %}
<p>You have already submitted a comment!</p>
{% elif request.user.profile == project.owner %}
<p>You can't comment your own work!</p>
{% elif request.user.is_authenticated %}
<form class="form" action="{% url 'project' project.id %}" method="POST">
{% csrf_token %}
{% for field in form %}
<div class="form__field">
<label for="formInput#textarea">{{field.label}} </label>
{{field}}
</div>
{% endfor %}
<input class="btn btn--sub btn--lg" type="submit" value="Add Review" />
</form>
{% else %}
Please login to leave a comment
{% endif %}
It was working okay when first implemented and has somehow developed this issue
This is running in venv with Python 3.9.6
Thank you for considering this question !
ADDED - rendered html
rendered html

Related name returning post.commentpost.none

Can anyone explain me, why i get Post.CommentPost.None?
How to correct connect CommentPost with Posty in query? I need get {{posty.comments.user}} my result is Post.CommentPost.None
Here something about my models and functions.
class Posty(models.Model):
title = models.CharField(max_length=250, blank=False, null=False, unique=True)
sub_title = models.SlugField(max_length=250, blank=False, null=False, unique=True)
content = models.TextField(max_length=250, blank=False, null=False)
image = models.ImageField(default="avatar.png",upload_to="images", validators=[FileExtensionValidator(['png','jpg','jpeg'])])
author = models.ForeignKey(Profil, on_delete=models.CASCADE)
updated = models.DateTimeField(auto_now=True)
published = models.DateTimeField(auto_now_add=True)
T_or_F = models.BooleanField(default=False)
likes = models.ManyToManyField(Profil, related_name='liked')
unlikes = models.ManyToManyField(Profil, related_name='unlikes')
created_tags = models.ForeignKey('Tags', blank=True, null=True, related_name='tagi', on_delete=models.CASCADE)
test_wyswietlenia = models.IntegerField(default=0, null=True, blank=True)
class CommentPost(models.Model):
user = models.ForeignKey(Profil, on_delete=models.CASCADE)
post = models.ForeignKey(Posty, on_delete=models.CASCADE, related_name="comments")
content1 = models.TextField(max_length=250, blank=False, null=False)
date_posted = models.DateTimeField(default=timezone.now)
date_updated = models.DateTimeField(auto_now=True)
VIEWS
tag = request.GET.get('tag')
if tag == None:
my_tag = Posty.objects.prefetch_related('comments')
my_view = Posty.objects.prefetch_related('my_wyswietlenia')
else:
my_tag = Posty.objects.filter(created_tags__tag=tag)
my_view = Posty.objects.prefetch_related('my_wyswietlenia')
TEMPLATES
{% for post in my_tag %}
{% if post.comments.last.user == None %}
<span class="forum_tag_author">Komentarz » Brak komentarza</span><br/>
<span class="forum_tag_author">Stworzony przez » {{post.author}} </span><hr/>
{% else %}
<span class="forum_tag_author">Komentarz » {{post.comments.last.content1}}</span><br/>
<span class="forum_tag_author">Odpowiadający » Dodany przez: {{post.comments.last.user}} </span><hr/>
{% endif %}
{% endfor %}
And this
{{post.comments}} give a request Post.CommentPost.None
What is problem? What i do bad?
You can use a Subquery expression [Django-doc] to obtain the latest content1 comment and author with:
from django.db.models import OuterRef, Subquery
last_comment = CommentPost.objects.filter(post=OuterRef('pk')).order_by('-date_posted')
my_tag = Posty.objects.annotate(
last_comment=Subquery(last_comment.values('content1')[:1]),
last_comment_user=Subquery(last_comment.values('user__name')[:1]),
last_comment_user_pk=Subquery(last_comment.values('user')[:1])
).prefetch_related('my_wyswietlenia')
The __name might be different, since it depends on the fields of you Profil model.
Then you can render the content and the last author with:
{% for post in my_tag %}
{{ post.last_comment }} by {{ post.last_coment_user }}
{% enfor %}

List of elements per category within for loop

I have a case, where on my template view I would like to display list of all objects (Issues) and categories (Sprints). I already applied also another filtering to display Issues that belongs to particular Project.
I've managed so far to display Sprints and within each Sprint I am displaying list of issues. How can I apply additional filtering on issues, that only issues belongs to particular sprint will be displayed?
Final result should be to display list of all issues divided per sprint.
My code below:
#views.py
class ProjectBacklogView(DetailView):
model = Project
template_name = 'project-backlog.html'
context_object_name = 'backlog'
def get_context_data(self, **kwargs):
context = super(ProjectBacklogView, self).get_context_data(**kwargs)
context['project'] = Project.objects.all()
context['issue'] = Issue.objects.all().order_by('sprint')
# context['epic'] = Epic.objects.all()
# context['initiative'] = Initiative.objects.all()
context['sprint'] = Sprint.objects.all()
return context
# template.html
{% extends 'base-project.html' %}
{% block content %}
{% for sprint in backlog.sprint_set.all %}
<h4>{{ sprint.name }}</h4>
<div id="simpleList" class="list-group" style="margin-bottom: 2%;">
{% for issue in backlog.issue_set.all %}
<div class="list-group-item">
<div style="float:left;"><strong>{{ issue.title }}</strong></div>
<div style="float: right;"><i class="fas">{{ issue.remaining_estimate }}</i></div>
<br /><br /><hr style="border-top: dashed 1px;"></hr>
<div style="float: left;"><small>Assignee: <strong>{{ issue.assignee }}</strong></small></div>
<div style="float: right;"><small>Initiative: <strong>{{ issue.initiative }}</strong></small></div><br />
<div style="float: left;"><small>Priority: <strong>{{ issue.priority }}</strong></small></div>
<div style="float: right;"><small>Epic: <strong>{{ issue.epic }}</strong></small></div>
</div>
{% endfor %}
<br />
</div>
{% endfor %}
{% endblock %}
#models.py
class Project(models.Model):
PROJECT_TYPE = (
('SCR', 'Scrum'),
('KAN', 'Kanban'),
)
# slug = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
alias = models.CharField(max_length=8, primary_key=True)
name = models.CharField(max_length=160)
project_type = models.CharField(max_length=10, choices=PROJECT_TYPE, default="SCR")
lead = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
# Definicja nazwy modelu w Adminie Django
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('project-detail', args=[str(self.alias)])
class Sprint(models.Model):
# sprint_type = models.TextField(default='Sprint', editable=False)
name = models.CharField(max_length=32)
goal = models.TextField(null=True, blank=True)
start_date = models.DateField()
end_date = models.DateField()
project = models.ForeignKey(Project, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Issue(models.Model):
ISSUE_PRIORITY = (
('Critical', 'C'),
('High', 'H'),
('Medium', 'M'),
('Low', 'L'),
)
issue_type = models.TextField(default='Issue', editable=False)
issue_id = models.AutoField(primary_key=True)
# slug = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
title = models.CharField(max_length=128)
description = models.TextField(null=True, blank=True)
initiative = models.ForeignKey(Initiative, on_delete=models.CASCADE, null=True, blank=True)
epic = models.ForeignKey(Epic, null=True, blank=True, on_delete=models.CASCADE)
sprint = models.ForeignKey(Sprint, on_delete=models.CASCADE, null=True, blank=True)
priority = models.CharField(max_length=8, choices=ISSUE_PRIORITY, default='Medium')
assignee = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='assignees', null=True, blank=True) # zczytywane z tabeli userów
author = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='authors') # zczytywane z tabeli userów
remaining_estimate = models.IntegerField(null=True, blank=True, default='0') # w minutach
time_logged = models.IntegerField(default='0') # w minutach
attachment = models.FileField(null=True, blank=True) # To Do - multiple files??
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('issue-detail', args=[str(self.issue_id)])
My issue is I don't know how to apply dynamically filter (based on field sprint) as sprints are listed in for loop

Django display related count

i currently try to display who many posts a category has.
Therefor i created the Post Model and the Category Model (See below):
models.py
# Categorys of Post Model
class Category(models.Model):
title = models.CharField(max_length=255, verbose_name="Title")
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ['title']
def __str__(self):
return self.title
#Post Model
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField(max_length=10000)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, null=True)
tag = models.CharField(max_length=50, blank=True)
postattachment = fields.FileField(upload_to='postattachment/%Y/%m/%d/', blank=True, null=True)
postcover = fields.ImageField(upload_to='postcover/%Y/%m/%d/', blank=True, null=True, dependencies=[
FileDependency(processor=ImageProcessor(
format='JPEG', scale={'max_width': 300, 'max_height': 300}))
])
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
category_list.html
{% extends 'quickblog/base.html' %}
{% block content %}
{% for categories in categories %}
<div>
<h1><u>{{ categories.title }} {{ $NumCountGetHere }}</u></h1>
</div>
{% endfor %}
{% endblock %}
Now i have no idea how to get the related objects counted...?
You can use something like this:
{% for cat in categories %}
<div>
<h1><u>{{ cat.title }} {{ cat.post_set.count }}</u></h1>
</div>
{% endfor %}
The model Post has a Foreignkey field to the model Category. You can access the related Post instances from a given Category instance using the manager category_instance.post_set. Read about it in the docs.
Finally, we use the method .count() on this manager to get the number of related posts for that given category. This way the code ends up looking like {{ cat.post_set.count }}.

django-haystack -- how to bring few apps under the same search page?

Django-haystack has examples of how to make one app searchable. We'll that is great!
However, when you have more than one app and each one is related to the User, how would you go about
having haystack (faceted) to allow you search for what you want. Let's say on all three of these models.
Example: Show me all male users who have a keyword of "experienced" in their description who also have
a skill with the name "Analyst" whose Info keywords contains "bla".
I googled with no result. So, I am looking at bringing few apps under the same search page.
class UserProfile(models.Model):
GENDER_MALE = 1
GENDER_FEMALE = 2
GENDER_CHOICES = (
(GENDER_MALE, 'Male'),
(GENDER_FEMALE, 'Female'),
)
user = models.OneToOneField(User, related_name="%(class)s", unique=True)
full_name = models.CharField(
_("Full name"),
max_length=200,
blank=True,
)
gender = models.IntegerField(
_('Gender'),
choices=GENDER_CHOICES,
blank=False,
null=True,
)
# common
country = CountryField(
_('Country'),
null=True,
blank=False,
)
# common
about = models.TextField(
_('About Me'),
blank=True,
validators=[MaxLengthValidator(400)],
)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __unicode__(self):
return u'%s' % (self.user.username)
class Skill(models.Model):
user = models.ForeignKey(
User,
related_name="%(class)s"
)
name = models.CharField(
_('Skill Name'),
max_length=70,
null=False
)
category = models.ForeignKey(
'self',
blank=True,
null=True
)
is_active = models.BooleanField(
default=True
)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __unicode__(self):
return u'%s' % (self.name)
class Info(models.Model):
user = models.ForeignKey(
User,
related_name="%(class)s",
null=False
)
description = models.TextField(
blank=False,
)
keywords = models.CharField(
blank=True,
null=True,
max_length=56,
)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __unicode__(self):
return u'%s' % self.title
I think if i am not wrong your question is to how to make facets work for multiple apps.
In url.py try something like
sqs = SearchQuerySet().facet('field1').facet('field2').facet('field3')
urlpatterns += patterns('haystack.views',
url(r'^$', FacetedSearchView(form_class=FacetedSearchForm, searchqueryset=sqs), name='haystack_search'),)
In search.html
{% if facets.fields.field1 %} {% for type1 in facets.fields.field1 %}
{{ type1.0 }} ({{ type1.1 }}) {% endfor %} {% else %}
No type1 facets.
{% endif %}
{% if facets.fields.field2 %} {% for author in facets.fields.field2 %}
{{ type2.0 }} ({{ type2.1 }}) {% endfor %} {% else %}
No type2 facets.
{% endif %}
{% if facets.fields.field3 %} {% for author in facets.fields.field3 %}
{{ type3.0 }} ({{ type3.1 }}) {% endfor %} {% else %}
No type3 facets.
{% endif %}
Your Apps should have individual search_index files .
Check the output of rebuild_index and update_index, whther indexing is done properly or not.