Django form not submit data - django

need your assistance in figuring out what is wrong with a form in my django app,i have a tab section in my app that has three tabs (lesson,workbook,answer).The work flow is that a user goes through some lesson content then clicks on a "take exercise" button which leads him to the workbook tab.Here i have questions which can either be multiple choice question or easy question depending on the lesson, after completing exercise a user submits the question and he transitions to the answers tab where his submitted answer is displayed in addition to the expected answer if he was wrong.My problem is that when the submit button is clicked the answers are not submitted and hence no user answers are displayed in the answer tab.
Here is the html code
<div class="tabs present-addition">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li {% if active_tab == "lesson" %}class="active"{% endif %}>Lesson Content</li>
<li {% if active_tab == "workbook" %}class="active"{% endif %}>Workbook</li>
<li {% if active_tab == "answers" %}class="active"{% endif %}>Answers</li>
</ul>
{% if messages %}
<div>{{ message }}</div>
<!--<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>-->
{% endif %}
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="lesson">
<p>{{ lesson.content|safe }}</p>
<!--<p>View Example</p>-->
{% if lesson.instructions_before %}
<h3>Instructions</h3>
<p>{{ lesson.instructions_before|safe }}</p>
{% endif %}
<div class="btn-container btn-container-info" id="wkbck">
<a class="btn btn-info btn--minimal btn-lg-bordered btn-inverse" href="#" data-toggle="tab" data-target="#workbook" >Take Exercise</a>
</div>
</div>
<div class="tab-pane" id="workbook">
{% if lesson.get_exercises %}
{% for exercise in lesson.get_exercises %}
<h4>{{ exercise.title }}</h4>
<form method="post" action="{% url 'exercise_submit' lesson.id exercise.id %}" class="contact" style="text-align:left;">
{% csrf_token %}
<input type="hidden" id="exercise_id" name="exercise_id" value="{{ exercise.id }}">
{% for question in exercise.question_set.all %}
<h6>{{ question.title }}</h6>
{% for answer in question.num_of_expected_answers|get_range %}
{{ forloop.counter }}: <input type="text" name="qu-{{ question.id }}-{{ forloop.counter }}" id="answer-{{ question.id }}-{{ forloop.counter }}" class="contact__field" style="width: 50%;" required /></br>
{% endfor %}
{% endfor %}
{% for mcquestion in exercise.multichoicequestion_set.all %}
<h6>{{ mcquestion.title }}</h6>
<div class="checkbox">
{% for option in mcquestion.multichoicequestionoption_set.all %}
{% with forloop.counter as curr_counter %}
<input type="checkbox" id="mcq-{{ mcquestion.id }}-{{ curr_counter }}" name="mcq-{{ mcquestion.id }}-{{ curr_counter }}" value="{{ option.content }}" >
<label for="mcq-{{ mcquestion.id }}-{{ curr_counter }}">{{ option.content }}</label>
{% endwith %}
{% endfor %}
</div>
</br>
{% endfor %}
{% for essay_question in exercise.essayquestion_set.all %}
<h6>{{ essay_question.title }}</h6>
<div class="modal-body">
<textarea rows="6" cols="50" class="contact__field contact__area" style="width: 50%;" name="eq-{{ essay_question.id }}" id="eq-{{ essay_question.id }}" placeholder="Type your answer here" required></textarea>
</div>
</br>
{% endfor %}
<div class="btn-container btn-container-info">
<button type="sumbit" class="btn btn-info btn--minimal btn-lg-bordered btn-inverse" data-toggle="tab" data-target="#answers" >Submit</button>
</div>
</form>
{% endfor %}
{% endif %}
<p>
<!--<div class="btn-container btn-container-info">
<a class="btn btn-info btn--minimal btn-lg-bordered btn-inverse" href="#"> Submit </a>
</div>-->
</p>
</div>
<div class="tab-pane" id="answers">
<h4>Exercise Answers</h3>
<!-- Display normal question answers -->
{% if questions and answers %}
{% for question in questions %}
<h6><b>{{ question.title }}</b></h6>
{% if answers %}
<ol>
{% for answer in answers %}
{% if answer.question.id == question.id %}
<li>{{ answer.answer }}</li>
{% endif %}
{% endfor %}
</ol>
{% endif %}
<h6>Expected Answer</h6>
<p>{{ question.expected_answer|safe }}</p>
<hr/>
{% endfor %}
{% endif %}
<!-- Display multichoice question answers -->
{% if multichoice_questions and mc_answers %}
{% for mc_question in multichoice_questions %}
<h6><b>{{ mc_question.title }}</b></h6>
{% if mc_answers %}
{% for mc_answer in mc_answers %}
{% if mc_answer.question.id == mc_question.id %}
<p>{{ mc_answer.selected_choice }}</p>
{% endif %}
{% endfor %}
{% endif %}
<h6>Expected Answer</h6>
<p>{{ mc_question.expected_answer|safe }}</p>
<hr/>
{% endfor %}
{% endif %}
<!-- Display essay question answers -->
{% if essay_questions and eq_answers %}
{% for es_question in essay_questions %}
<h6><b>{{ es_question.title }}</b></h6>
{% if eq_answers %}
{% for eq_answer in eq_answers %}
{% if eq_answer.question.id == es_question.id %}
<p>{{ eq_answer.answer }}</p>
{% endif %}
{% endfor %}
{% endif %}
<h6>Expected Answer</h6>
<p>{{ es_question.expected_answer|safe }}</p>
<hr/>
{% endfor %}
{% endif %}
<!-- This exercise has not been answered -->
{% if not answers and not mc_answers and not eq_answers %}
<p>Will be revealed after submitting your work.</p>
{% endif %}
<!-- Show next lesson button if available -->
{% if answers or mc_answers or eq_answers %}
{% if lesson.next_lesson %}
<p>
<div class="btn-container btn-container-warning">
<a class="btn btn-warning btn--minimal btn-lg-bordered btn-inverse" href="{% url 'learn_lesson' lesson.next_lesson.module.course.slug lesson.next_lesson.module.slug lesson.next_lesson.slug %}">Next Lesson</a>
</div>
</p>
{% endif %}
{% endif %}
</div>
</div>
</div>
<!-- end tabs -->
Here is the view.py
def lesson_exercise_posted(request, lesson_id, exercise_id):
if request.method == 'POST':
form = LessonExerciseForm(request.POST)
lesson = Lesson.objects.get(pk=lesson_id)
exercise = Exercise.objects.get(pk=exercise_id)
exercise_submission, created = ExerciseSubmission.objects.get_or_create(
student=request.user,
#lesson=lesson,
exercise=exercise)
if created:
for key in request.POST.iterkeys():
value = request.POST.get(key)
print("{0}:::{1}".format(key, value))
if value:
# Get Link Questions; Can be more than one
if key.startswith('qu'):
prefix, question_id, question_counter = key.split('-')
qu_question = Question.objects.get(pk=question_id)
user_answer = UserAnswer(student=request.user,
question=qu_question,
answer=value.strip(),
exercise_submission=exercise_submission)
user_answer.save()
# Get Multichoice Questions
if key.startswith('mcq'):
prefix, question_id, choice_counter = key.split('-')
mc_question = MultiChoiceQuestion.objects.get(pk=question_id)
mc_option_selected = MultiChoiceQuestionOption.objects.get(question=mc_question, content=value.strip())
mc_answer = MultiChoiceUserSubmittedAnswer(
student=request.user,
question=mc_question,
selected_choice=mc_option_selected,
exercise_submission=exercise_submission)
mc_answer.save()
# Get Essay Questions
if key.startswith('eq'):
prefix, question_id = key.split('-')
essay_question = EssayQuestion.objects.get(pk=question_id)
try:
essay_answer = EssayUserAnswer.objects.get(student=request.user, question=essay_question)
except EssayUserAnswer.DoesNotExist:
essay_answer = EssayUserAnswer(student=request.user,
question=essay_question,
answer=value.strip(),
exercise_submission=exercise_submission)
essay_answer.save()
# Update the user progress
progress = StudentLessonProgress.objects.get(student=request.user, lesson=lesson)
progress.status = COMPLETED
progress.done_percent = 100 # Incrementing percentage at this stage to make it 100
progress.save()
messages.success(request, "Thank you! Your answer submission has been saved. Click on the Answers tab to reveal the correct answers.")
else:
form = LessonExerciseForm()
messages.success(request, "Thank you! Your answer submission was NOT saved because you had previously done this exercise.")
return HttpResponseRedirect( '{0}#answers'.format(reverse('learn_lesson',
kwargs={
'form':form,
'course_slug':lesson.module.course.slug,
'module_slug':lesson.module.slug,
'lesson_slug':lesson.slug}
)))
Here is the models.py
class Exercise(models.Model):
title = models.CharField(max_length=256, null=True)
def __unicode__(self):
return self.title
class ExerciseSubmission(models.Model):
""" Data Model representing a student's exercise Submission. """
student = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='The Student', related_name='exercise_submissions')
exercise = models.ForeignKey(Exercise, verbose_name=_("Exercise"))
#lesson = get_model('jm_lms.apps.courses.models', 'Lesson') #models.ForeignKey(Lesson, verbose_name='Lesson')
date = models.DateTimeField(editable=False, auto_now_add=True)
class Meta:
verbose_name = _("Exercise Submission")
verbose_name_plural = _("Exercise Submissions")
class BaseQuestion(models.Model):
exercise = models.ForeignKey(Exercise, verbose_name=_("Exercise"))
title = models.TextField(verbose_name="Topic Box", blank=True, null=True)
expected_answer = models.TextField(verbose_name="Expected Answer", blank=True, null=True, help_text=_("How the learner should answer the question. Shown after the question has been answered."))
class Meta:
abstract = True
def __unicode__(self):
return self.title
class Question(BaseQuestion):
num_of_expected_answers = models.IntegerField(default=1, verbose_name=_("Number of expected answers"))
class Meta:
verbose_name = _("List Question")
verbose_name_plural = _("List Questions")
class UserAnswer(models.Model):
"""
Response given by a user
"""
student = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='The Student', related_name='exercise_answers')
question = models.ForeignKey(Question, verbose_name=_("Question"))
answer = models.CharField(max_length=256, null=True)
answered_on = models.DateTimeField(auto_now_add=True, blank=True, null=True)
exercise_submission = models.ForeignKey(ExerciseSubmission, verbose_name=_("Exercise Submission"), blank=True, null=True)
# status = models.IntegerField(verbose_name="Answer Status", choices=USER_ANSWER_STATUS, default=NOT_PUBLISHED, help_text='Enable user answer reference in the next Lesson')
class Meta:
ordering = ("id",)
verbose_name = _("User Answer to List Question")
verbose_name_plural = _("User Answers to List Question")
def __unicode__(self):
return self.answer
class MultiChoiceQuestion(BaseQuestion):
class Meta:
verbose_name = _("Multiple Choice Question")
verbose_name_plural = _("Multiple Choice Questions")
def check_if_correct(self, guess):
answer = MultiChoiceQuestionOption.objects.get(id=guess)
if answer.correct is True:
return True
else:
return False
def get_answers(self):
return MultiChoiceQuestionOption.objects.filter(question=self)
def get_answers_list(self):
return [(answer.id, answer.content) for answer in MultiChoiceQuestionOption.objects.filter(question=self)]
class MultiChoiceQuestionOption(models.Model):
question = models.ForeignKey(MultiChoiceQuestion, verbose_name=_("Question"))
content = models.CharField(max_length=1000,
blank=False,
help_text=_("Enter the answer text that you want displayed"),
verbose_name=_("Answer Content"))
correct = models.BooleanField(blank=False,
default=False,
help_text=_("Is this a correct answer?"),
verbose_name=_("Correct"))
class Meta:
verbose_name = _("MultiChoice Option")
verbose_name_plural = _("MultiChoice Options")
def __unicode__(self):
return self.content
class MultiChoiceUserSubmittedAnswer(models.Model):
student = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='The Student', related_name='exercise_submitted_choice')
question = models.ForeignKey(MultiChoiceQuestion, verbose_name=_("Question"))
selected_choice = models.ForeignKey(MultiChoiceQuestionOption, verbose_name=_("Question"))
answered_on = models.DateTimeField(auto_now_add=True, blank=True, null=True)
exercise_submission = models.ForeignKey(ExerciseSubmission, verbose_name=_("Exercise Submission"), blank=True, null=True)
# status = models.IntegerField(verbose_name="Answer Status", choices=USER_ANSWER_STATUS, default=NOT_PUBLISHED, help_text='Enable user answer reference in the next Lesson')
class Meta:
verbose_name = _("MultiChoice Submitted User Answer")
verbose_name_plural = _("MultiChoice Submitted User Answers")
def __unicode__(self):
return self.selected_choice.content
class EssayQuestion(BaseQuestion):
class Meta:
verbose_name = _("Essay Question")
verbose_name_plural = _("Essay Questions")
class EssayUserAnswer(models.Model):
student = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='The Student', related_name='exercise_essay_answers')
question = models.ForeignKey(EssayQuestion, verbose_name=_("Question"))
answer = models.TextField(null=True, blank=True)
answered_on = models.DateTimeField(auto_now_add=True, blank=True, null=True)
exercise_submission = models.ForeignKey(ExerciseSubmission, verbose_name=_("Exercise Submission"), blank=True, null=True)
# status = models.IntegerField(verbose_name="Answer Status", choices=USER_ANSWER_STATUS, default=NOT_PUBLISHED, help_text='Enable user answer reference in the next Lesson')
# class TableExerciseQuestion(BaseQuestion):
# class Meta:
# verbose_name = _("Table Exercise Question")
# verbose_name_plural = _("Table Exercise Questions")
#
#
# class TableExercise(models.Model):
# """
# Model to enable lesson developer to add lesson exercise fields headers ,description e.t.c
# """
# question = models.ForeignKey(TableExerciseQuestion, verbose_name=_("Question"))
# field_name = models.CharField(max_length=200)
# field_occurrence = models.IntegerField(default=1, verbose_name=_("Number of expected fields"))
Here is the forms.py
class LessonExerciseForm(forms.ModelForm):
model = [MultiChoiceQuestion, ExerciseSubmission, EssayQuestion]
fields = '__all__'

I had very similar problem while dealing with different issue. But I think your problem is the same.
link to post
Basically the problem was the html code. I would suggest that you verify your generated html code in browser and check if the form tags are closed properly. It might be the case that form tags are closed earlier than your data is coming later in html and it wouldn't be submitted. Check generated html.

Related

Django Display count of database entries related via foreign key

I have two models, ProjectNotes and ProjectNoteComments. ProjectNoteComments are related to ProjectNotes via a foreign key. I want to display the number of comments each note has on a listview. I am just learning Django and so far I have not been able to figure out how to retrieve and display the comment count.
My view:
(I do import count)
class ProjectNotesList(ListView):
model = ProjectNotes
template_name = 'company_accounts/project_notes.html'
comments = ProjectNotes.comments
def related_project(self, **kwargs):
project = get_object_or_404(Project, id=self.kwargs.get('pk'))
notes = ProjectNotes.objects.all
return notes
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
context['project'] = get_object_or_404(Project, id=self.kwargs.get('pk'))
return context
commentscount = ProjectNotes.objects.annotate(num_comments=Count('comments'))
My template:
{% extends 'base.html' %}
{% block content %}
<div class="section-container container">
<h1>Notes for {{ project }}</h1>
{% if project.notes.all %}
{% for note in project.notes.all %}
<div class ="projectnotes-entry">
<div class="col-sm-8">
<div class="row-sm-6">
<div class="card mb-2">
<div class="card-body">
<div class="card-title">{{ note.title }}</div>
<div class="card-text">{{ note.body | safe | truncatewords:"20"|linebreaks }}
read more</div>
</div>
</div>
</div>
</div>
</div>
<h2>comments count</h2>
{{ commentscount }}
{% endfor %}
{% else %}
<p>No notes have been have been added yet.</p>
{% endif %}
</div>
{% endblock content %}
The models:
class ProjectNotes(models.Model):
title = models.CharField(max_length=200)
body = tinymce_models.HTMLField()
date = models.DateField(auto_now_add=True)
project = models.ForeignKey(Project, default=0, blank=True, on_delete=models.CASCADE, related_name='notes')
def __str__(self):
return self.title
class ProjectNoteComments(models.Model):
body = tinymce_models.HTMLField()
date = models.DateField(auto_now_add=True)
projectnote = models.ForeignKey(ProjectNotes, default=0, blank=True, on_delete=models.CASCADE, related_name='comments')
Short version:
{{ note.comments.all.count }} # possibly works also without 'all' but can't check right now
I've just answered similar problem with simple explanation of relationships.
https://stackoverflow.com/a/70955851/12775662
Read official docs, it's really rewarding. https://docs.djangoproject.com/en/4.0/topics/db/models/#relationships

How to create a django formset or form add/edit page in order to edit several records

For one of my open source projects, I need to create ONE add/edit page in order to make possible to edit several records with one save.
The repo is an IMDB clone formed for learning purpose. A user can add her/his favorite genres in her/his profile. Then an edit page is formed to show the list of those favored genres and the movies within that genre. (A for loop here) User can add notes, watch list options and so on to those movies. (NOT a FORMSET)
However, the code doesn't work as expected. The page cannot be saved and only the first checkbox of the list can be changed.
There is no error.
NOTE:
You can install repo with dummy data.
(https://github.com/pydatageek/imdb-clone)
Then after logging in, select your favorite genres. (http://localhost:8000/users/profile/)
Then (I wish it can be solved here) you can see the movies with your selected genres. Add notes, to watch list... (http://localhost:8080/users/profile/movies2/)
# users/templates/user-movies-with_loop.html
{% extends 'base.html' %}{% load crispy_forms_tags %}
<!-- Title -->
{% block htitle %}Your movies from favorite genres{% endblock %}
{% block title %}Your movies from favorite genres{% endblock %}
{% block content %}
<div class="card card-signin">
{% include 'users/profile-menu.html' %}
<h3 class="card-title text-center my-4">Take notes for your movies <small></small></h3>
<hr class="mb-1">
<div class="card-body">
<form method="POST">
{% csrf_token %}
{% for genre in user.genres.all %}
<h2 for="genre" name="genre" value="{{ genre.id }}">{{ genre.name }}</h2>
{% for movie in genre.movies.all %}
<div class="ml-5">
<h4>{{ movie.title }}</h4>
{{ form|crispy }}
</div>
<input type="hidden" name="user" value="{{ user.id }}">
<input type="hidden" name="movie" value="{{ movie.id }}">
{% empty %}
<p class="alert alert-danger">The genre you have selected on your profile doesn't have any movies!</p>
{% endfor %}
{% empty %}
<p class="alert alert-danger">You should select genres with movies from your profile to edit here!</p>
{% endfor %}
<input class="btn btn-lg btn-primary btn-block text-uppercase" type="submit" value="Submit">
</form>
</div>
</div>
{% endblock %}
# users.forms.py
...
class UserMovieFormWithLoop(ModelForm):
genre = forms.HiddenInput(attrs={'disabled': True})
class Meta:
model = UserMovie
fields = ('user', 'movie', 'note', 'watched', 'watch_list')
widgets = {
'user': forms.HiddenInput,
'movie': forms.HiddenInput,
'watched': forms.CheckboxInput(),
}
...
# users.models.py
...
class UserMovie(models.Model):
"""
Users have notes about their favorite movies.
"""
user = models.ForeignKey(User, on_delete=models.CASCADE)
movie = models.ForeignKey('movies.Movie', default=1, on_delete=models.CASCADE)
note = models.CharField(max_length=250, null=True, blank=True)
watched = models.BooleanField(default=False, verbose_name='Have you seen before?')
watch_list = models.BooleanField(default=False, verbose_name='Add to Watch List?')
def __str__(self):
return f'{self.user.username} ({self.movie.title})'
...
# users.views.py
...
class UserMovieViewWithLoop(LoginRequiredMixin, CreateView):
model = UserMovie
template_name = 'users/user-movies-with_loop.html'
form_class = UserMovieFormWithLoop
success_message = 'your form has been submitted.'
success_url = reverse_lazy('users:user_movies2')
def form_valid(self, form):
user = self.request.user
movie_counter = Movie.objects.filter(genres__in=user.genres.all()).count()
f = form.save(commit=False)
f.user = user
for i in range(movie_counter):
f.pk = None
f.save()
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super(UserMovieViewWithLoop, self).get_context_data(**kwargs)
context['form'] = self.form_class
return context
def get_object(self):
user = self.request.user
return UserMovie.objects.get(user=user)
...

Why the attribute of an instance model does not change

I create a financial manager and I need the user to change the account activity (indicate an active account or not), but when I send the form for change, then the model attribute does not change and always remains TRUE
I also tried to do this through a copy of the Account, but it was also not a result of the outcome
Account.objects.get(user=self.request.user, id=id).is_active = False
models.py
class Account(models.Model):
type_of_currency = models.CharField(max_length=20)
user = models.ForeignKey(get_user_model(), blank=True,
related_name='user_account',
on_delete=models.CASCADE)
count = models.DecimalField(max_digits=12, decimal_places=2, blank=True)
created = models.DateTimeField(default=datetime.datetime.now)
is_active = models.BooleanField()
def __str__(self):
return f'{self.type_of_currency} - {self.count}'
views.py
class AccountDetailView(DetailView, UpdateView):
model = Account
form_class = AccountCreateForm
template_name = 'account_detail.html'
def post(self, request, *args, **kwargs):
id = self.request.POST['accountid']
self.request.user.user_account.get(id=6).is_active = False
print(self.request.user.user_account.get(
id=id).is_active) # always True why?
return redirect('/counts/' + id)
template
{% extends 'base.html' %}
{% block content %}
<div class="col-sm-5">
<h1>account: {{ account.id }}</h1>
<p><strong>Author:</strong> {{ account.user }}</p> <!-- author detail link not yet defined -->
<p><strong>Type:</strong> {{ account.type_of_currency }}</p>
<p><strong>count:</strong> {{ account.count }}</p>
<p><strong>IsCreated:</strong> {{ account.created }}</p>
<p><strong>IsActive:</strong>{{ account.is_active }}</p>
<a class="btn btn-outline-primary"
href="{% url 'account-list' %}">Back</a>
{% if account.is_active %}
<form method="post">
{% csrf_token %}
<input type="hidden" value="{{ account.id }}" name="accountid">
<button type="submit" class="btn btn-outline-danger">Deactivate</button>
</form>
{% else %}
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-outline-success">Activate</button>
</form>
{% endif %}
</div>
{% endblock %}
In the post method DetailViews, I expect that after the button is pressed, user activity will change, but the result is always True
You're never commiting change to DB.
Also, I wouldn't use the following syntax: self.request.user.user_account.get(id=6).is_active = False
You can try: self.request.user.user_acocount.filter(id=6).update(is_active=False)
But, if you're dead set on using .get():
user_acc = self.request.user.user_account.get(id=6)
user_acc.is_active = False
user_acc.save()

How to implement the paginator in Django 2.1?

To product page of my project I need to add paginator. I did according to the Django Documentation but I have the following error:
object of type 'InsuranceProducts' has no len()
Here is the my views.py:
def farmer_types(request, type_id):
product_areas = InsuranceProducts.objects.filter(product_type="Фермерам")
product_types = get_object_or_404(InsuranceProducts, id=type_id)
paginator = Paginator(product_types, 6)
page = request.GET.get('page')
types = paginator.get_page(page)
context = {'product_types': product_types,
'product_areas': product_areas,
'types': types}
return render(request, 'insurance_products/farmer/farmer_types.html', context)
Here is the my models.py:
class InsuranceProducts(models.Model):
product_area = models.CharField(max_length=100)
product_description = models.TextField()
product_type = models.CharField(max_length=50)
def __str__(self):
return "{}-{}".format(self.product_area, self.product_type)
class ProductType(models.Model):
product_area = models.ForeignKey(InsuranceProducts, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
description = models.TextField()
body = HTMLField('Content')
def __str__(self):
return "{} - {}".format(self.product_area, self.title)
Here is the code from the template:
{% for product in types.producttype_set.all %}
<div class="btmspace-80">
<h3>{{ product.title|upper }}</h3>
<img class="imgr borderedbox inspace-5" src="{% static 'img/imgr.gif' %}" alt="">
<p>
{{ product.description|upper }}
</p>
<p>
Подробно вы можете узнать о новости здесь</a>
</p>
</div>
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if types.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ types.number }} of {{ types.paginator.num_pages }}.
</span>
{% if types.has_next %}
next
last »
{% endif %}
</span>
</div>
<!-- ################################################################################################ -->
</div>
I did the everything as it is given in the Docs.
Why is product_types plural if you are using get_object_or_404, which returns only one object?
You're doing the pagination right, but doing the query wrong. If you change paginator = Paginator(product_types, 6) to paginator = Paginator(product_areas, 6), you will see that it works perfectly fine.
You should read the documentation on how to do queries, and understand the relationships between models.

django - getting the requested user object in the template through models method

Please have a look at this code:
models:
class Activity(models.Model):
actor = models.ForeignKey(User)
action = models.CharField(max_length=100)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)
class Meta:
verbose_name = 'Activity'
verbose_name_plural = 'Activities'
ordering = ['-pub_date']
def __unicode__(self):
return ("%s %s") % (self.actor.username, self.action)
def get_rendered_html(self):
template_name = '%s_activity.html' %(self.content_type.name)
return render_to_string(template_name, {
'object':self.content_object,
'actor':self.actor,
'action':self.action,
})
template:
<div class="user_activity">
<p>{{ actor.username }} {{ action }} {{ object.content_object.user.username }} status</p>
<p>{{ object.content_object.body }}</p>
<p>{{ object.content_object.pub_date }}</p>
{% if object.content_object.image %}
<div class="activity_img_wrapper">
<p><img src="/media/{{ object.content_object.image }}"/></p>
</div>
{% endif %}
</div>
Question
How do I get the requested user's username for the above template (request.user). I did like this, but it didn't help :
<div class="user_activity">
<p>
{% if user.username == actor.username %}
You
{% else %}
{{ actor.username }}
{% endif %}
{{ action }}
{% if user.username == object.content_object.user.username %}
Your
{% else %}
{{ object.content_object.user.username }}
{% endif %}
status
</p>
<p>{{ object.content_object.body }}</p>
<p>{{ object.content_object.pub_date }}</p>
{% if object.content_object.image %}
<div class="activity_img_wrapper">
<p><img src="/media/{{ object.content_object.image }}"/></p>
</div>
{% endif %}
</div>
Please help me how to do it. I would really be grateful for your help. Thank you.
There is no RequestContext object available in the get_rendered_html() method so you can't pass it as a context_instance argument of the render_to_string(). This is why the user variable is not available in the template.
You should pass the User instance to get_rendered_html() method and propagate it to the template:
def get_rendered_html(self, user=None):
template_name = '%s_activity.html' %(self.content_type.name)
return render_to_string(template_name, {
'object':self.content_object,
'actor':self.actor,
'action':self.action,
'user':user,
})
If you want to call this method from other template then the best option is to use custom template tag:
# app/templatetags/activity_tags.py
# and don't forget to create empty app/templatetags/__init__.py :-)
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
#register.simple_tag(takes_context=True)
def render_activity(context, activity):
user = context['user']
html = activity.get_rendered_html(user)
return mark_safe(html)
And then load and use this tag library in your template:
{% load activity_tags %}
...
{% render_activity activity %}