Django 1.7, template not displaying data from views.py - python

python 3.4.2
django 1.7.1
postgres 9.4
I am attempting to query data from postgres and send it to the template for rendering.
I've included the models, views, urls.py, and the media page
I think the issue is in views.py, and the contextDict var I send to the template.
What should be happening:
user hits index.html and clicks a link to view more information about a media asset
index.html loads the views.py 'media' function
media function captures the slugify URL and uses it to query the DB
the 'media' function in views.py loads the data into variables
the 'media' function passes the request, template url, and variables to the template
the template processes the variables and sends the page to the users client
what is happening
user hits index.html and clicks link to view more information about the media asset
index.html loads the views.py mdia function
the user sees a rendered page with text "The specified project {{projectSlugTitle}} does not exist"
what I think the problem is
step 3-6 is f**** up, I think the problem lies either in my query to the DB, or how i'm passing the data to the template
model:
from django.db import models
from django.utils import timezone
from django.template.defaultfilters import slugify
#table for media files: audio, video, design
class Media(models.Model):
#choicesConstants
#type
MEDIATYPE_FILM = 'MEDIATYPE_FILM'
MEDIATYPE_AUDIO = 'MEDIATYPE_AUDIO'
MEDIATYPE_DESIGN = 'MEDIATYPE_DESIGN'
#category
MEDIACATEGORY_MAJOR = 'MEDIACATEGORY_MAJOR'
MEDIACATEGORY_INDIE = 'MEDIACATEGORY_INDIE'
#genre
MEDIAGENRE_RAP = 'MEDIAGENRE_RAP'
MEDIAGENRE_ROCK = 'MEDIAGENRE_ROCK'
MEDIAGENRE_TECHNO = 'MEDIAGENRE_TECHNO'
#choicesList
choicesType = (
(MEDIATYPE_FILM,'Video'),
(MEDIATYPE_AUDIO,'Audio'),
(MEDIATYPE_DESIGN,'Design'),
)
choicesCategory = (
(MEDIACATEGORY_INDIE,'Indie'),
(MEDIACATEGORY_MAJOR,'Major'),
)
choicesGenre = (
(MEDIAGENRE_RAP,'Rap'),
(MEDIAGENRE_ROCK,'Rock'),
(MEDIAGENRE_TECHNO,'Techno')
)
#boolean
mediaPublished = models.BooleanField(default=True)
#char fields
title = models.CharField(max_length=256,blank=True)
type = models.CharField(max_length=256,choices=choicesType, default=MEDIATYPE_FILM)
category = models.CharField(max_length=256,choices=choicesCategory,default=MEDIACATEGORY_MAJOR)
genre = models.CharField(max_length=256,choices=choicesGenre,default=MEDIAGENRE_TECHNO)
#integer fields
views = models.IntegerField(default=0)
upVotes = models.IntegerField(default=0)
downVotes = models.IntegerField(default=0)
#date fields
dateAdded = models.DateTimeField(default=timezone.now)
datePublished = models.DateTimeField(blank=True,null=True)
dateDePublished = models.DateTimeField(blank=True,null=True)
#urlfields
intUrl = models.URLField(blank=True)
extUrl = models.URLField(blank=True)
#email fields
mediaEmail = models.EmailField(max_length=254,blank=True)
#decimalFields
mediaB2bPrice = models.DecimalField(max_digits=20,decimal_places=2,default=0)
mediaB2cPrice = models.DecimalField(max_digits=20,decimal_places=2,default=0)
#slugFields
slug1 = models.SlugField()
#functionUtility
def __str__(self):
return self.title
#functionMath
def totalVotes(self):
return int(self.upVotes)+int(self.downVotes)
def percentUpVotes(self):
return int(self.upVotes)/int(self.totalVotes)
def percentDownVotes(self):
return int(self.downVotes) / int(self.totalVotes)
def save(self, *args,**kwargs):
self.slug1 = slugify(self.title)
super(Media, self).save(*args, **kwargs)
#metaData
class Meta:
ordering = ['dateAdded','title']
get_latest_by = 'dateAdded'
verbose_name = 'Media'
verbose_name_plural = 'Media'
#tablef for projects, contain multiple media files
class Project(models.Model):
#manyToMany relationships
media = models.ManyToManyField(Media,null=True,blank=True)
#boolean
projectPublished = models.BooleanField(default=True)
#charFields
title = models.CharField(blank=True,max_length=256)
#textFields
projectDescription = models.TextField(blank=True)
#email fields
projectEmail = models.EmailField(max_length=254,blank=True)
#dateFields
dateCreated = models.DateTimeField(default=timezone.now)
datePublished = models.DateTimeField(blank=True,null=True)
#decimalFields
projectB2bPrice = models.DecimalField(max_digits=20,decimal_places=2,default=0)
projectB2cPrice = models.DecimalField(max_digits=20,decimal_places=2,default=0)
#slugFields
slug1 = models.SlugField()
#functionsUtility
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug1 = slugify(self.title)
super(Project, self).save(*args, **kwargs)
#metaData
class Meta:
ordering = ['dateCreated','title']
get_latest_by = 'dateAdded'
verbose_name = 'Project'
verbose_name_plural = 'Projects'
view:
def project(request,theProjectSlug):
contextDict = {}
try:
#retrieve the project with the matching slug name
project = Project.objects.get(slug1=theProjectSlug)
contextDict['projectName'] = project.title
#retrieve all of the associated media files of the project above
mediaFiles = Media.objects.all().filter(project=project)
#add mediaFiles to contextDict,add the project to the contextDict
contextDict['mediaFilesOfProject'] = mediaFiles
contextDict['project'] = project
except Project.DoesNotExist:
pass
return render(request, 'famecity/media.html', contextDict)
urls.py:
urlpatterns = patterns('',
url(r'^$',views.index,name='index'),
url(r'^about/',views.about,name='about'),
url(r'^media/(?P<theProjectSlug>[\w\-]+)/$',views.project,name='project')
)
the rendered page:
<!DOCTYPE html>
<html>
<head>
<title>Fame.city Projects
</title>
</head>
<body>
<h1>
projectName: {{ projectName }}<br/>
mediaFilesOfProject: {{mediaFilesOfProject}}<br/>
project: {{project}}<br/>
</h1>
{% if project %}
{% if media %}
<ul>
{% for mFile in media %}
<li>
{{mFile.title}}
</li>
{% endfor %}
</ul>
{% else %}
<strong>No media files exist</strong>
{% endif %}
{% else %}
The specified project {{projectSlugTitle}} does not exist
{% endif %}
</body>
</html>

Found the issue
I was querying the Project table instead of the Media table
when the user hits index.html and clicks the media link, my code above sent create an SQL to the Project table, and the error cascades from there because of the subsequent lines are based on the initial value of the first variable.

Related

How to show history of orders for user in Django

I will pin some screenshots of my template and admin panel
I have history of orders in admin panel but when im trying to show title and img of order product in user profile in my template that`s not working and i got queryset
Im sorry for russian words in my site, i can rescreen my screenshots if you need that
models.py
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='orders', verbose_name='Заказы',
default=1)
username = models.CharField(max_length=50, verbose_name='Имя пользователя')
email = models.EmailField()
vk_or_telegram = models.CharField(max_length=255, verbose_name='Ссылка для связи', default='vk.com')
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False, verbose_name='Оплачено')
class Meta:
ordering = ['-created',]
verbose_name = 'Заказ'
verbose_name_plural = 'Заказы'
def __str__(self):
return 'Заказ {}'.format(self.id)
def get_cost(self):
return sum(item.get_cost() for item in self.items.all())
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='order', on_delete=models.CASCADE)
product = models.ForeignKey(Posts, related_name='order_items', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return '{}'.format(self.id)
def get_cost(self):
return self.price
views.py
#login_required
def profile(request):
user_orders = Order.objects.filter(user=request.user)
data = {
'user_orders': user_orders,
}
return render(request, 'store/main_pages/profile.html', data)
order history template:
{% for item in user_orders %}
{{ item }}
{{ item.order.all }}
{% endfor %}
Profile template
admin order panel
Create a model for storing the orders. This model should have fields for storing information about the order, such as the total cost, the date the order was placed, and the status of the order.
Create a view that will display the order history for a user. This view should retrieve all of the orders for the logged-in user from the database and pass them to a template.
Create a template to display the order history. This template should loop through the list of orders passed to it by the view and display the relevant information for each order.
Add a URL pattern to your Django project's urls.py file that maps to the view that displays the order history.
Add a link to the order history page in your application's navigation menu or elsewhere on the site.
In user_orders = Order.objects.filter(user=request.user)
you have all of the user's order histories.
when sending these data to the front, don't use {{ item.order.all }}
each of your items is an order.
I found solution, OrderItem has product, which is a ForeignKey for my product with title, content and img
Views.py changed for:
#login_required
def profile(request):
user_orders = Order.objects.filter(user=request.user)
user_order_item = OrderItem.objects.all()
data = {
'user_orders': user_orders,
'user_order_item': user_order_item,
}
return render(request, 'store/main_pages/profile.html', data)
Template:
{% if user_orders %}
{% for item in user_order_item %}
<p>{{ item.product.title }}</p>
<p><img src="{{ item.product.photo.url }}" alt=""></p>
% endfor %}
{% endif %}

How to view multiple images under separate posts in profile page?

I am building a social media website. On the profile page and home page are different posts. Each can have multiple images. I created a different model for images and set ForeignKey to Post model. The form for uploading text and images works fine because the images attach to each post in the database.
However, I am having issues writing the views code for the page they are to display. I am getting just text with no images.
I am trying to add an Id to each post in the views but I have no idea how to do that since they are all in one page and therefore have no separate urls.
I don't know if that is the right approach.
models.py
class Tweets(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
note = models.TextField(blank=False,)
date_posted = models.DateTimeField(auto_now_add=True)
url = models.URLField(max_length=200, blank=True)
likes = models.IntegerField(default=0)
def __str__(self):
# if len(self.note) > 60:
# return f"{self.note[:60]}... --- (Posted {self.when_tweeted} ago) by [{self.profile.name}]"
# if self.when_tweeted.title() == "Just Now":
# return f"{self.note[:60]}... --- (Posted {self.when_tweeted}) by [{self.profile.name}], {self.likes} likes"
# else:
# if self.when_tweeted == "Just Now":
# return f"{self.note[:60]}... --- (Posted {self.when_tweeted}) by [{self.profile.name}]"
# return f"{self.note} --- (Posted {self.when_tweeted} ago) by [{self.profile.name}]"
return f"{self.note}({self.id})"
class Meta:
ordering = ['-date_posted']
verbose_name_plural = 'Tweets'
#property
def tweet_id(self):
return self.id
class Images(models.Model):
tweet = models.ForeignKey(Tweets, on_delete=models.CASCADE, related_name='images')
image = models.ImageField(blank=True, upload_to='image/tweets_image')
class Meta:
verbose_name = 'Image'
verbose_name_plural = 'Images'
def __str__(self):
return self.image.url
views.py
def profile_index(request, user_id, *args, **kwargs):
users = User.objects.all()
profiles = Profile.objects.all()
user = get_object_or_404(User, id=user_id)
profile = get_object_or_404(Profile, id=user_id)
tweets = Tweets.objects.all().filter(user=user)
id_list = []
for t in tweets:
id=t.id
print(id)
id_list.append(id)
print(id_list)
target_tweet = get_object_or_404(Tweets, id=id)
tweet_images = target_tweet.images.all()
context = {
'user': user,
'profile': profile,
'tweets': tweets,
'users': users,
'profiles': profile,
'target_tweet': target_tweet,
'tweet_images': tweet_images
}
return render(request, 'twee/profile_index.html', context)
profile.html
{% if tweet == target_tweet %}
{% for img in tweet_images %}
<img class="post-image" src="{{ img.image.url }}" alt="">
{% endfor %}
{% endif %}

Update button not getting the query

thanks for your time:
I've got a model that is linked to the user and the only one that can update him its his creator. untill that works fine. just the creator user can open the url update although i'm not beeing able to pass a button on the main template of the model with redirect to that update url.
i'd like to know if there is a way to that button apear just to his user (if not ok, to get in just open to the matching queryset user).
Or just why this button ain't working: i should get the url eg:services/parceiro/update/2 i'm beeing able to open this url if i'm the creator user but when i try to set it in a button i get this error:
Reverse for 'update_parceiro2' with arguments '('',)' not found. 1 pattern(s) tried: ['services/parceiro/update/(?P[0-9]+)$']
parceiros.html:
{% extends "base.html" %}
{% block content %}
<h1>{{parc.nome}} - {{parc.user}} - {{parc.responsavel}}</h1>
<form action="{% url 'update_parceiro2' Parceiros.id %}">
<button type="submit"><i class="material-icons">sync</i></button>
</form>
{% endblock %}
views.py:
def parceirosview(request, pk=None):
parc = get_object_or_404(Parceiros, id=pk)
context = {'parc': parc}
return render(request, 'parceiro.html', context)
def get_queryset(self):
return super().get_queryset().filter(parceiro__user=self.request.user)
class ParceiroUpdate(UpdateView):
model = Parceiros
template_name = 'parceiroform.html'
fields = ['nome', 'endereco', 'responsavel', 'tel']
def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)
urls.py:
urlpatterns = [
path('home/', views.home_view, name='home2'),
path('parceiro/', views.parceirosview, name='parceiro2'),
path('parceiro/detail/<int:pk>', views.parceirosview, name='parceiro_detail2'),
path('addparceiro/', views.parceiros_create, name='add_parceiro2'),
path('parceiro/detail2/<int:pk>', ParceirosView.as_view(), name='parceiro_detail22'),
path('parceiro/update/<int:pk>', ParceiroUpdate.as_view(), name='update_parceiro2')
]
models.py:
get_user_model = User
class Parceiros (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
nome = models.CharField(max_length=200)
endereco = models.TextField(max_length=400, blank=True)
responsavel = models.CharField(max_length=100)
tel = PhoneField(max_length=12)
created_at = models.DateTimeField(auto_now=True)
updated_at = models.DateTimeField(auto_now_add=True, blank=True)
ativo = models.BooleanField(default=False)
def get_queryset(self):
queryset = super(Parceiros, self).get_queryset()
return queryset
def __str__(self):
return '%s %s' % (self.user, self.nome)
def get_absolute_url(self):
return reverse('parceiro_detail2', kwargs={'pk': self.pk})
You can use this code in your template to display content for user based on his id
{% if request.user.id == 1 %}
<form action="{% url 'update_parceiro2' Parceiros.id %}">
<button type="submit"><i class="material-icons">sync</i></button>
</form>
{% endif %}

Django view with get context not working

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.

Fixed a bug of views django: Page not found

My english is not good !
I have tried many ways but still get error: page not found.
File views.py:
def create_article(request, template_name='vlogntruong/create_article.html'):
if request.method == "POST":
create_form = VlogForm(request.POST)
if create_form.is_valid():
new_article = create_form.save()
return HttpResponeRedirect(new_article.get_absolute_url())
else:
create_form = VlogForm(request)
template_context = {
'create_form': create_form,
}
return render_to_response(
template_name,
template_context,
RequestContext(request)
)
File forms.py
from django import forms
from .models import VlogNTruong
class VlogForm(forms.Form):
title= forms.CharField(max_length=100,
widget=forms.TextInput(attrs={'size':50}))
name = forms.CharField(max_length=50,
widget = forms.TextInput(attrs={'size':50}))
sumary = forms.CharField(widget = forms.Textarea(attrs={"rows":10, "cols":80}))
content = forms.CharField(widget = forms.Textarea(attrs={"rows":20, "cols":80}))
video = forms.CharField(required = False,
widget = forms.TextInput(attrs={'size':60}))
def save(self):
create_form = VlogNTruong(title = self.cleaned_data['title'],
name = self.cleaned_data['name'],
sumary = self.cleaned_data['content'],
content = self.cleaned_data['content'],
video = self.cleaned_data['video'])
create_form.save()
return create_form
File models.py:
from django.db import models
from django.db.models import permalink
from embed_video.fields import EmbedVideoField
from django.template.defaultfilters import slugify
from django.contrib import admin
import datetime
class VlogNTruong (models.Model):
title = models.CharField(max_length=100)
slug_field = models.TextField(null=True, blank=True)
name = models.CharField(max_length=50)
sumary = models.TextField()
content = models.TextField()
time_create = models.DateTimeField(auto_now_add=True)
video = EmbedVideoField(null=True, blank=True)
class Meta:
ordering = ('-time_create',)
def __unicode__(self):
return "%s" % self.title
#permalink
def get_absolute_url(self):
return ('vlogntruong.views.article_detail', [self.slug_field])
def save(self, *args, **kwargs):
if not self.slug_field:
self.slug_field = slugify(self.title)
super(VlogNTruong, self).save(*args, **kwargs)
file html
{% extends 'vlogntruong/base.html' %}
{% block panel_content %}
<form action="/" method="post">{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit" name="Create" />
</form>
{% endblock %}
file urls
urlpatterns = patterns('vlogntruong.views',
url(r'^$', 'list_article',
{'template_name':'vlogntruong/list_article.html'}),
url(r'^(?P<slug_field>[-\w\d]+)/$', 'article_detail'),
url(r'^create/$', 'create_article'),
)
Help me
Error
Page not found (404)
Request Method: GET
Request URL: /nhuttruong/create/
No VlogNTruong matches the given query.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
Your problem is that your save() method in your form is not returning the object it creates in the database, it is returning the unsaved instance, for which you are trying to get the redirect url.
I would suggest you read the modelforms guide to help you along.
Your form should look like this:
from django import forms
from .models import VlogNTruong
class VlogForm(forms.ModelForm):
title= forms.CharField(max_length=100,
widget=forms.TextInput(attrs={'size':50}))
name = forms.CharField(max_length=50,
widget = forms.TextInput(attrs={'size':50}))
sumary = forms.CharField(widget = forms.Textarea(attrs={"rows":10, "cols":80}))
content = forms.CharField(widget = forms.Textarea(attrs={"rows":20, "cols":80}))
video = forms.CharField(required = False,
widget = forms.TextInput(attrs={'size':60}))
class Meta:
model = VlogNTruong
Then, in your views, you need to adjust it like this:
from django.shortcuts import render
def create_article(request, template_name='vlogntruong/create_article.html'):
create_form = VlogForm(request.POST or None)
if create_form.is_valid():
new_article = create_form.save()
return HttpResponeRedirect(new_article.get_absolute_url())
template_context = {'create_form': create_form,}
return render(request, template_name, template_context)
You also need to make sure that the VlogNTruong model has a get_absolute_url method which returns a URL. Your method just returns a tuple, fix it like this:
def get_absolute_url(self):
from django.core.urlresolvers import reverse
return reverse('vlogntruong.views.article_detail', args=[self.slug_field])
Finally your __unicode__ method must return a unicode object, yours is returning a string:
def __unicode__(self):
return unicode('{}'.format(self.title))
The regular expression that you are using in the third url() does not match with the requested URL:
r'^create/$' will not match '/nhuttruong/create/'
To achieve your objective you should use something like r'.+/create/$'

Categories

Resources