When I got this error I understood that I didn't learn URL -HTML- views-model relationship. First, let me show my codes.
This is my views.py:
def category_detail(request, category_name):
links = Link.objects.filter(category__name=category_name)
return render_to_response("category_detail.html", {"links":links}, context_instance=RequestContext(request))
This is models.py:
class Category(models.Model):
name = models.CharField(_("Category"), max_length=255)
user = models.ManyToManyField(User)
def __unicode__(self):
return "%s %s" %(self.user, self.name)
def admin_names(self):
return ', '.join([a.username for a in self.user.all()])
admin_names.short_description = "User Names"
def get_absolute_url(self):
return "/category/%s" % self.name
class Link(models.Model):
user = models.ForeignKey(User)
posted_at = models.DateTimeField(auto_now_add=True)
url = models.URLField()
title = models.CharField(max_length=255, null=True, blank=True)
category = models.ForeignKey(Category)
def __unicode__(self):
return "%s %s %s" %(self.url, self.title, self.category)
This is HTML page:
<div id="profilemenu">
index<p>
{% for category in categories %}
<p>{{category.name }}
{% endfor %}
<p>
</div>
and urls.py:
url(r'^category/(?P<category_name>.*)', 'link.views.category_detail', name="category_detail"),
When I click a category name to open category_detail.html, the URL in browser is like :
http://127.0.0.1:8000/category`/
I can't get categoryname. Please can you tell me my stupid mistake? :\ Thanks for time.
If you are using the namespace in your urls you would need to reference it without quotes in the template.
<p>{{category.name }}
Note: You'll want to ensure the namespace is fully qualified. If you have embedded namespaces you should separate them with :.
<p>{{category.name }}
Hopefully this solves your problem.
You should follow get_absolute_url reference:
def get_absolute_url(self):
from django.core.urlresolvers import reverse
return reverse('link.views.category_detail', args=[str(self.name)])
html
{{ category.name }}
Related
I have a following models.py for my Django blog, I made a following views.py to pass the value of the slug for my URL parameter.
However I am struggling to create a model in views to get other data(person & description) from Category class.
I have tried some patterns by myself but can not pass them to HTML. (always Error or not showing)
Can you please give me some idea of how to solve this.
models.py
class Category(models.Model):
person = models.CharField(max_length=20)
description = models.TextField()
slug = models.SlugField()
def __str__(self):
return self.person
views.py
def blog_category(request, category):
posts = Post.objects.filter(categories__slug__contains=category).order_by("-created_on").distinct()
context = {"category": category, "posts": posts}
return render(request, "blog_category.html", context)
HTML(Localhost:8000/slug)
{{ person }}
{{ description }}
this is full code of my models.py
class Category(models.Model):
person = models.CharField(max_length=20)
description = models.TextField()
slug = models.SlugField()
def __str__(self):
return self.person
class Recommender(models.Model):
recommender_name = models.CharField(max_length=20)
slug = models.SlugField()
def __str__(self):
return self.recommender_name
class Post(models.Model):
book_title = models.CharField(max_length=255)
author = models.CharField(max_length=255)
book_link = models.CharField(max_length=255)
recommenders = models.ForeignKey("Recommender", on_delete=models.CASCADE,)
source = models.TextField()
source_link = models.CharField(max_length=255)
created_on = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
categories = models.ManyToManyField("Category", related_name="posts")
slug = models.SlugField()
def __str__(self):
return self.book_title
posts = Post.objects.filter(categories__slug__contains=category).order_by("-created_on").distinct()
Is going to return a queryset. It can have more than one instance of the model class (since you are using filter). In your context you are sending this queryset as posts to your templates.
So in your HTML you can use something like this. You need to use a for loop since there can be more than one item in posts.
{% for post in posts %}
{% for category in post.categories.all %}
{{ category.person }}
{{ category.description }}
{% endfor %}
{% endfor %}
I would look at this example.
Namely, if you render the template like it is shown in the example, you should be able to do
{{ category.person }} {{ category.description }}
Have a quick question. Trying to use a relational model in one DetailView. However, no matter what I try the data does not display. I've tried a few versions of template tags to no avail.
html
{% for parts in relatedparts %}{{ parts.name }}
</div>{% endfor %}
views.py
class ErrorCodeView(DetailView):
context_object_name = 'error_code_details'
model = models.ErrorCodes
template_name = 'error_code_details.html'
def get_context_data(self, **kwargs):
# xxx will be available in the template as the related objects
context = super(ErrorCodeView, self).get_context_data(**kwargs)
context['relatedparts'] = RelatedParts.objects.filter(name=self.get_object())
return context
models.py
class ErrorCodes(models.Model):
name = models.CharField(max_length=256)
description = models.CharField(max_length=400)
instructions = models.CharField(max_length=256)
PartsNeeded = models.CharField(max_length=120, default='')
usercomments = models.CharField(max_length=400, default='', blank=True)
relpic = models.ImageField(upload_to='media/',blank=True)
relpictwo = models.ImageField(upload_to='media/',blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("errorcodes:errorcodeview",kwargs={'name':self.name})
class RelatedParts(models.Model):
name = models.CharField(max_length=256)
related_error_code = models.ForeignKey(ErrorCodes, on_delete=models.PROTECT)
def __str__(self):
return self.name
You don't need to do this at all. You can follow the relationship in the template.
{% for part in object.relatedparts_set.all %}{{ part.name }}{% endfor %}
You don't need any code in the view to enable this.
could it be that "name=self.get_object()" should be "name=self.get_object().name" ?
You currently have:
context['relatedparts'] = RelatedParts.objects.filter(name=self.get_object())
but that is probably producing an empty queryset.
I'm having some trouble displaying data from my database on the template in django
model:
class CityInfo (models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
landmark_type = models.CharField(blank=True, max_length=30)
business = 'Business'
student = 'Student'
tourist = 'Tourist'
def __str__(self):
return self.name
relevant view:
def itemget(request):
data=CityInfo.objects.all()
return render(request,'CityApp/infopage.html', {'data': data})
relevant url:
url(r'itemget/$',views.itemget,{'template_name': 'CityApp/info_page.html'},name='itemget'),
infopage.html:
<ul>
{% for item in data %}
<li>
<h1>{{ item.name }}</h1>
</li>
{% endfor %}
<ul>
The above html results in a blank list and I have no idea why.
Try changing views.py to the following:
def itemget(request):
data = CityInfo.objects.all()
context={
'data': data
}
return render(request, "CityApp/infopage.html", context)
Try this :
def __str__(self):
return "%s" % self.name
I'm not sure because I'm on my old smartphone.
Otherwise, your def __str__ is well indented in your class ?
Are you using Python 2 or Python 3 ? str if for Python 3. Else you have to use __unicode__
EDIT :
From you urls.py file, you have :
url(r'itemget/$',views.itemget,{'template_name': 'CityApp/info_page.html'},name='itemget'),
Remove your template_name part which is already in your view and don't forget to add ^ before itemget
url(r'^itemget/$',views.itemget ,name='itemget'),
Hi I have to following Models.py
class Question(models.Model):
user = models.ForeignKey(User)
article = models.ForeignKey(Article)
number = models.CharField("문제번호", max_length=10, null=True, blank=True)
q_type = models.CharField("문제유형", max_length=15)
question = models.TextField("문제내용")
answer = models.TextField("답안", null=True, blank=True)
reference = models.TextField("참고사항", null=True, blank=True)
def __str__(self):
return "%s번: %s" % (self.number, self.question)
class Professor(models.Model):
question = models.OneToOneField(Question, null=True, blank=True, related_name="related_professor")
articles = models.ManyToManyField(Article, null=True, blank=True)
name = models.CharField("교수이름", max_length=20)
def __str__(self):
return "%s" % (self.name,)
Views.py:
def read_q_table(request, board_id, article_id):
article = get_object_or_404(Article, id=article_id)
context = {
"boards" : Board.objects.all(),
"board_id" : board_id,
"questions" : Question.objects.all().order_by("number"),
"article" : article,
"professor" : Professor.objects.all()
}
return render(request, "q_table.html", context)
Template:
{% if questions %}
{% for question in questions %}
<div class="list-group-item">
<div class="row text-center">
<div class="col-xs-2 col-md-2">{{ question.related_professor.name }}</div>
</div>
</div>
{% endfor %}
{% else %}
What I want is to access professor name field in template. I have passed in context the list of "question" class objects to template, and I would like to use OneToOneField attribute somehow to access related professor name in template.
According to Accessing Django OneToOneField in templates?, {{ question. related_professor.name }} should work, but it doesn't. Can anyone help?
Thanks.
Or, it could be a problem with saving the professor data in the first place. The following code takes form input and submit them to save them.
Professor.objects.get(name=professor).question = question_instance
Professor.objects.get(name=professor).save()
These two lines in def submit_question may raise an eyebrow but I am not sure. Here I am trying to get the related professor instance and update its question field(a OneToOneField that relates to Question class).
def submit_question(request, board_id, article_id):
article = get_object_or_404(Article, id= article_id)
try:
professor = request.POST["professor"].strip()
q_type = request.POST["q_type"].strip()
question = request.POST["question"].strip()
number = request.POST["number"].strip()
reference = request.POST["reference"].strip()
if request.POST['q_type']== "주관식":
answer = request.POST['d_answer'].strip()
else:
answer = request.POST['m_answer'].strip()
except KeyError:
request.session["error"] = "올바른 요청이 아닙니다."
return redirect("read_article", board_id, article_id)
if professor and q_type and question:
question_instance = article.question_set.create(q_type = q_type, question = question, user_id = request.user.id)
Professor.objects.get(name=professor).question = question_instance
Professor.objects.get(name=professor).save()
if number:
question_instance.number = number
if answer:
question_instance.answer = answer
if reference:
question_instance.reference = reference
question_instance.save()
else:
request.session["error"] = "출제교수, 문제유형 및 문제는 필수 입력 항목입니다."
return redirect("read_article", board_id, article_id)
return redirect("read_q_table", board_id, article_id)
These two lines are suspect:
Professor.objects.get(name=professor).question = question_instance
Professor.objects.get(name=professor).save()
The second line will get the Professor from the database again, and it won't have your question instance attached anymore when you save it. Try this instead:
prof = Professor.objects.get(name=professor)
prof.question = question_instance
prof.save()
I've recently been trying to implement full text search on my webapp with Django Haystack (v2.1.0) with Elasticsearch (v0.90.5) as my search engine. My goal is to be able to, with one query, search through a title field, key line field, and an authors field for a given Song object. Here is my code:
Models.py
class Song(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
key_line = models.CharField(max_length=300, blank=True)
def __unicode__(self):
return self.title
class Author(models.Model):
first_name = models.CharField(max_length=30)
middle_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, verbose_name='e-mail')
def __unicode__(self):
if self.middle_name:
return u'%s %s %s' % (self.first_name, self.middle_name, self.last_name)
else:
return u'%s %s' % (self.first_name, self.last_name)
class Meta:
ordering = ('last_name','first_name')
Search_index.py
from haystack import indexes
from songs.models import Song
class SongIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
content_auto = indexes.EdgeNgramField(model_attr='title')
content_auto = indexes.EdgeNgramField(model_attr='key_line')
authors = indexes.MultiValueField()
content_auto = indexes.EdgeNgramField(model_attr='authors')
def get_model(self):
return Song
def prepare_authors(self, object):
return [author.last_name for author in object.authors.all()]
def index_queryset(self, using=None):
return self.get_model().objects.all()
song_text.txt
{{ object.title}}
{{ object.key_line}}
{% for author in object.authors.all %}
{{ author.last_name}}
{% endfor %}
I'm sure my search_index.py is terribly wrong for the authors but I was getting desperate. I've been able to get the title and the key_line to work properly in that if i type in a query, I get results that have the query in the title or have the query in the key line. Performing the same test but instead querying the author's last name doesn't give me results with that author.
I've gone through the documentation and though I've found some information on indexing related fields, I haven't been able to find anything specific related to using EdgeNGrams with a related field. Is this possible to do? Ideally, I'd like to be able to query over the author's first, middle, and last name.
Thanks in advance for any help you can give! Let me know if you need any more information.
Similar problem is addressed # Haystack search on a many to many field is not working
def prepare_category(self, obj):
return [category.name for category in obj.category_set.all()]
Your code should be ;
def prepare_authors(self, object):
return [author.last_name for author in object.authors_set.all()]
Change song_text.txt to ;
{{ object.title}}
{{ object.key_line}}
{% for author in object.authors.all %}
{{ author.first_name}}
{{ author.middle_name}}
{{ author.last_name}}
{% endfor %}
Changing object.authors.all() to object.authors_set.all() should solve this problem.