Django - View is not rendering to HTML - python

Pretty straight forward question….
My view named create_view renders data correctly out of my model and my other view named create_view_two view doesn’t.
How do I get my view named create_view_two to render data to home.html?
Cheers
user_profile/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.http import HttpResponseNotFound
from django.shortcuts import get_object_or_404
from django.shortcuts import render, redirect
from django.conf import settings
from .forms import HomeForm
from .models import Listing
from users.models import CustomUser
def create_view(request):
form = HomeForm(request.POST or None, request.FILES or None,)
user_profile = Listing.objects.all()
user = request.user
if request.method == "POST":
if form.is_valid():
listing_instance = form.save(commit=False)
listing_instance.user = user
listing_instance.save()
return redirect("myaccount")
context = {
'form': form, 'user_profile': user_profile
}
return render(request, "myaccount.html", context)
def create_view_two(request):
form_two = HomeForm(request.POST or None, request.FILES or None,)
user_profile_two = Listing.objects.all()
user = request.user
context = {
'form': form_two, 'user_profile': user_profile_two
}
return render(request, "home.html", context)
user_profile/models
from django.contrib import auth
from django.db import models
from django.urls import reverse
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from users.models import CustomUser
class Listing (models.Model):
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True, null=True)
updated = models.DateTimeField(auto_now=True)
rank = models.CharField(max_length=100, null=True)
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
zip_code = models.CharField(max_length=100)
mobile_number = models.CharField(max_length=100)
cc_type = models.CharField(max_length=100, null=True)
cc_number = models.CharField(max_length=100, null=True)
cc_expiration = models.CharField(max_length=100, null=True)
cc_cvv = models.CharField(max_length=100, null=True)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = Listing.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=CustomUser)
user_profile/urls.py
from django.conf.urls import url
from . import views
from django.urls import path, include
from django.conf import settings
from .views import create_view, create_view_two
urlpatterns = [
path('myaccount/', create_view, name='myaccount'),
path('home/', create_view_two, name='home'),
]
home.html
{% for profile_two in user_profile_two %}
{{ user_profile_two }}
{% endfor %}
myaccount.html
{% for profile in user_profile %}
<div class="user-info-heading payments-detail">
<p>Card Number:</p><span>{{ profile.cc_type }}</span>
<p>Card Type:</p><span>{{ profile.cc_number }}</span>
<p>Expiration Date:</p><span>{{ profile.cc_expiration }}</span>
<p>CVV:</p><span>{{ profile.cc_cvv }}</span>
</div>
{% endfor %}

In your home.html you should have:
{% for profile_two in user_profile %}
instead of:
{% for profile_two in user_profile_two %}
Given user_profile is the name you're giving it in the context dict.
UPDATE
If your code is exactly as you updated it, then your home.html should be like this:
{% for profile_two in user_profile %}
{{ profile_two }}
{% endfor %}

Related

How to resolve user into the field?

I'm creating a simple To Do app using Django 3.2, and I have stuck in a error which is: FieldError: Cannot resolve keyword 'user' into field. Choices are: content, created, email, id, name, user1, user1_id
This is models.py:
from django.db import models
from django.db.models.deletion import CASCADE
from django.db.models.fields import CharField
from django.contrib.auth.models import User
# Create your models here.
class User(models.Model):
content = models.CharField(max_length=200, null=True)
created = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
user1 = models.ForeignKey(User, on_delete=CASCADE)
def __str__(self):
return self.content
forms.py
from django import forms
from django.forms import ModelForm, fields
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email', 'password1', 'password2']
views.py
from django.shortcuts import render, redirect
from django.http.response import HttpResponse
from django.utils import timezone
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from demo.forms import CreateUserForm
from .models import *
from .models import __str__
# Create your views here.
#login_required(login_url='/login')
def home(request):
user = request.user
all_items = User.objects.filter(user=user).order_by("created")
context = {'all_items': all_items}
return render(request, 'html/home.html', context)
#login_required(login_url='/login')
def add_content(request):
current_date = timezone.now()
newItem = User(content=request.POST.get('content'))
newItem.save()
return redirect('/')
#login_required(login_url='/login')
def login_user(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('/')
return render(request, 'html/login.html')
def logoutUser(request):
logout(request)
return redirect('login/')
def register_user(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.save()
user = authenticate(request, username=user.username, password=request.POST.get('password1'))
if user is not None:
login(request, user)
return redirect('/')
context = {'form':form}
return render(request, 'html/register.html', context)
home.html
<div>
<form class="felx" action="add_content/" method="POST">
{% csrf_token %}
<input class="form-control me-2" type="text" name="content" placeholder="Hey">
<button id="add-btn" class="button" type="submit">Add</button>
</form>
<table>
<thead>
{% for all_item in all_items %}
<tr>
<td>{{ all_item.content }}</td>
</tr>
{% endfor %}
</thead>
</table>
Logout
{% if request.user.is_authenticated %}
<p>Hello {{request.user}}</p>
{% endif %}
</div>
By far, any data that is added can be access by every account, but what i'm trying to do is that each user has his own data or tasks in this case.
Would appreciate any idea!
Thanks
i think your problem is here
#login_required(login_url='/login')
def home(request):
user = request.user.pk
all_items = User.objects.filter(user1_id=user).order_by("created") #new
context = {'all_items': all_items}
return render(request, 'html/home.html', context)
#login_required(login_url='/login')
def add_content(request):
current_date = timezone.now()
newItem = User(content=request.POST.get('content'),user1_id=request.user.pk)
newItem.save()
return redirect('/')
Advice:Please try to change the User in models.py to an other name because Django has by default a model called User.

Can't get forms to render in Django

I'm working on a project and I don't get the django forms to render on any of my pages. I've compared it to django girls code, as that is what I usually consult but it looks virtually identical to it. It's not just this page, my other pages have issues with rendering the forms as well. Here's the code:
Views.py
from django.shortcuts import render
from .models import *
from .forms import *
from django.shortcuts import render, get_object_or_404
from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.db.models import Sum
from django.utils import timezone
from django.views.decorators.http import require_POST
from .cart import Cart
from django.db import transaction
from django.contrib import messages
#login_required
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = PostForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = PostForm(instance=Post)
return render(request, 'rentadevapp/post_edit.html', {'rentadevapp': post_edit}, {'form': form})
Forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'text',)
post_edit.html
{% extends 'rentadevapp/base.html' %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{% block content %}
<head>
<link rel="stylesheet" href="{% static 'css/post_edit.css' %}">
</head>
<body>
<div class="container"><br>
<h2>New Post</h2><br>
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
</div>
</body>
{% endblock %}
Models.py
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
updated_date = models.DateTimeField(auto_now_add=True)
price = models.DecimalField(max_digits=10, decimal_places=2, default='0')
class Meta:
ordering = ('title',)
def created(self):
self.created_date = timezone.now()
self.save()
def updated(self):
self.updated_date = timezone.now()
self.save()
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
I'm pretty stuck and have spent a couple hours trying to figure this out. Any help is really appreciated.
Thanks!
Your form isn't returned to the template in the context.
In Django 1.11 or 2.2 the render function call in your view should return a dictionary of context variables as the third argument, but you've got two dictionaries. The 4th argument where you've got a dictionary containing the form is being passed as content_type which is then used in the HttpResponse so I'm quite surprised there isn't something strange happening or an error seen.
So you're doing;
return render(request, 'rentadevapp/post_edit.html', {'rentadevapp': post_edit}, {'form': form})
What you need to do is;
context = {'form': form, 'rentadevapp': post_edit}
return render(request, 'rentadevapp/post_edit.html', context)
Prior to 1.10 render had a different signature, but the first three arguments of request, template_name, context have been that way since <1.8

How to access pk in views (Django)

I'm writing a small chat programm in Django but have problems getting any further.
Here's the code:
models.py
from django.db import models
from datetime import datetime
from django.utils import timezone
class Chat(models.Model):
chatname = models.CharField(max_length=100)
description = models.TextField()
created_at = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.chatname
class Comment(models.Model):
chat = models.ForeignKey(Chat, on_delete=models.CASCADE)
commenter = models.CharField(max_length=30)
comment = models.TextField()
created_at = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.comment
urls.py
from django.conf.urls import url
from . import views
from django.views.generic import ListView
from chat.views import CommentList
app_name = 'chats'
urlpatterns = [
url(r'^$', views.index, name="index"),
url(r'^comments/(?P<pk>[0-9]+)/$', views.CommentList.as_view(), name='comments'),
]
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth import authenticate, login
from django.views import generic
from .models import Chat, Comment
def index(request):
username = None
if request.user.is_authenticated():
username = request.user.username
chats = Chat.objects.all()[:10]
context = {
'chats':chats
}
return render(request, 'chat/index.html', context)
class CommentList(generic.ListView):
queryset = Comment.objects.filter(chat_id=1)
context_object_name = 'comments'
My comment_list.html
{% extends "chat/base.html" %}
{% block content %}
Go back
<h3>Comments</h3>
<h2>{{chat.id}}</h2>
<ul>
{% for comment in comments %}
<li>{{ comment.commenter }}: {{ comment.comment }}</li>
{% endfor %}
</ul>
{% endblock %}
My database structure contains these two models: Chat and Comment. Each chat(room) is supposed to have its own comments. I used 'models.ForeignKey' to be able to filter the comments for each chat(room). In my index.html I list all the chats and each of these has a hyperlink to the /comments/ section.
In my views.py I have this line: 'queryset = Comment.objects.filter(chat_id=1)'
Chat_id is the column in the comments sql table and as it is now it will only show comments that belong to the chat with pk=1. How can I auto access the chat for the different urls /comments/1/ /comments/2/ and so on..?
Hope the explanation is clear. Sorry beginner here, I can try to explain further if it doesn't make a lot of sense.
Best,
Fabian
You should define the get_queryset method instead of the standalone queryset attribute.
def get_queryset(self, *args, **kwargs):
return Comment.objects.filter(chat_id=self.kwargs['pk'])
Instead of CommentList you can use plain view:
def comments_index(request, chatid):
return render(request, 'xxx/comment_list.html', {
'comments': Comment.objects.filter(chat_id=chatid)
})
And in urls:
url(r'^comments/(?P<chatid>[0-9]+)/$', views.comments_index, name='comments'),

django edit and upload image from templates

every one,,I have a template it can edit my data to database,however,when I try to upload an image from the templates ,,,just fail,,can any one tell me how can I code it and work well,thank you
models.py
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
from django.utils import timezone
def get_imagep_Product(instance, filename):
return '/'.join(['products', instance.slug, filename])
class ProductsTbl(models.Model):
model_number = models.CharField(max_length=255, blank=True, null=True)
name = models.CharField(max_length=255, blank=True, null=True)
material = models.TextField(blank=True, null=True)
feature = models.TextField(blank=True, null=True)
created = models.DateTimeField(editable=False)
modified = models.DateTimeField(auto_now=True)
release = models.DateTimeField(blank=True, null=True)
submit_date = models.DateTimeField(blank=True, null=True)
slug = models.SlugField(unique=True)
user = models.ForeignKey(User, blank=True, null=True)
image = models.ImageField(upload_to=get_imagep_Product, blank=True) #try to upload this image from templates
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.id:
self.created = timezone.now()
return super(ProductsTbl, self).save(*args, **kwargs)
....
views.py
from django.shortcuts import render,redirect
from .forms import ProductsTblForm,ProductsTblUploadForm
from .models import ProductsTbl,Upload
from django.template.defaultfilters import slugify
from django.contrib.auth.decorators import login_required
from django.http import Http404,HttpResponse
import datetime
....
#login_required
def edit_thing(request, slug):
# grab the object...
thing = ProductsTbl.objects.get(slug=slug)
if thing.user != request.user:
raise Http404
# set the form we're using...
form_class = ProductsTblForm
if request.method == 'POST':
# grab the data from the submitted form
form = form_class(data=request.POST,instance=thing)
if form.is_valid():
# save the new data
form.save()
return redirect('thing_detail', slug=thing.slug)
# otherwise just create the form
else:
form = form_class(instance=thing)
# and render the template
return render(request, 'things/edit_thing.html', {
'thing': thing,
'form': form,
})
....
urls.py
from django.conf.urls import patterns, url,include
from django.contrib import admin
from django.views.generic import TemplateView
from designer import views
from designer.backends import MyRegistrationView
from django.conf import settings
urlpatterns = [
....
url(r'^things/(?P<slug>[-\w]+)/edit/$', views.edit_thing, name='edit_thing'),
....
]
if settings.DEBUG:
urlpatterns += [
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
]
forms.py
from django.forms import ModelForm
from .models import ProductsTbl,Upload
class ProductsTblForm(ModelForm):
class Meta:
model = ProductsTbl
fields = ('model_number','name','feature', 'material','release','image',)
....
edit_thing.html
....
{% extends 'base.html' %} {% block title %}
Edit {{ thing.name }} - {{ block.super }} {% endblock title %}
{% block content %}
<h1>Edit "{{ thing.name }}"</h1>
<form role="form" action="" method="post" enctype="multipart/form-data" >
{% csrf_token %}
{{ form.as_p }}
<br>
<button type="submit">Submit</button>
Edit images
</form>
{% endblock %}
when I create things ,,I can upload image just like link here I asked yesterday
,however,,when I try to edit the form and upload an image just fail,,I do not know why?thank you
I solved the problem in views.py:
By changing following:
form = form_class(data=request.POST, instance=thing)
to:
form = form_class(data=request.POST, files=request.FILES, instance=thing)

Django Many-to-Many Accessing both Models

I'm looking to build a small 'Twitter style' site using Django to get to grips with things and have decided to try and allow multiple users edit each post (eventually based on permissions). Now what I'm struggling with is accessing each user's posts. Below is the code for my model, view and template which shows "There aint no post here" for all users. I'm looking to be able to show all posts that the user has and don't seem to be getting anywhere:
models.py
from django.db import models
class User(models.Model):
username = models.CharField(max_length = 200)
email = models.EmailField(max_length = 75)
password = models.CharField(max_length = 64)
created_date = models.DateTimeField('date created')
def __unicode__(self):
return self.username
class Meta:
ordering = ('created_date',)
class Post(models.Model):
users = models.ManyToManyField(User)
title = models.CharField(max_length = 300)
post = models.TextField()
posted_date = models.DateTimeField('date created')
votes = models.IntegerField()
def __unicode__(self):
return self.title
class Meta:
ordering = ('posted_date',)
views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from users.models import User, Post
def index(request):
latest_user_list = User.objects.order_by('username')[:5]
context = {'latest_user_list': latest_user_list}
return render(request, 'users/index.html', context)
def detail(request, user_id):
user = get_object_or_404(User, pk=user_id)
post_list = Post.objects.filter(id == user.id)
return render(request, 'users/detail.html', {'user': user, 'post': post_list})
urls.py
from django.conf.urls import patterns, url
from users import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^(?P<user_id>\d+)/$', views.detail, name='detail'),
)
(template) - detail.html
<h1>{{ user.username }}</h1>
{% if post_list %}
<ul>
{% for post in post_list%}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% else %}
<p> There aint no posts here </p>
{% endif %}
The variable you're passing to the template is called post not post_list.
Change the name for the list object in your view.
def detail(request, user_id):
user = get_object_or_404(User, pk=user_id)
post_list = Post.objects.filter(id == user.id)
return render(request, 'users/detail.html', {'user': user, 'post_list': post_list})

Categories