Django,Profile matching query does not exist error at profile/1 - python

Whenever I click on the profiles(links) on the profile_list page, I get the profile doesn't exist error
it always goes to profiles that do not longer exist in the database.
Models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class Profile(models.Model):
user=models.OneToOneField(User,on_delete=models.CASCADE)
follows=models.ManyToManyField(
"self",
related_name="followed_by",
symmetrical=False,
blank=True)
def __str__(self):
return self.user.username
#receiver(post_save,sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
user_profile=Profile(user=instance)
user_profile.save()
user_profile.follows.add(instance.profile)
user_profile.save()
admin.py:
from django.contrib import admin
from django.contrib.auth.models import Group,User
from .models import Profile
class ProfileInline(admin.StackedInline):
model=Profile
class UserAdmin(admin.ModelAdmin):
model=User
fields=["username"]
inlines=[ProfileInline]
# Register your models here.
admin.site.unregister(Group)
admin.site.unregister(User)
admin.site.register(User,UserAdmin)
views.py:
from django.urls import reverse
from django.shortcuts import render
from requests import request
from users.models import Profile
from django.http import HttpResponseRedirect
# Create your views here.
def dashboard(request):
return render(request,"inbox/layout.html")
def feed(request):
return render(request,"inbox/feed.html")
def outbox(request):
return render(request,"inbox/outbox.html")
def profile_list(request):
profiles=Profile.objects.exclude(user=request.user)
return render(request,"inbox/profile_list.html",{"profiles":profiles})
def profile(request, pk):
if not hasattr(request.user, 'profile'):
missing_profile = Profile(user=request.user)
missing_profile.save()
profile = Profile.objects.get(pk=pk)
if request.method == "POST":
current_user_profile = request.user.profile
data = request.POST
action = data.get("follow")
if action == "follow":
current_user_profile.follows.add(profile)
elif action == "unfollow":
current_user_profile.follows.remove(profile)
current_user_profile.save()
return render(request, "inbox/profile.html", {"profile": profile})
profile.html:
<!-- inbox/templates/inbox/profile_list.html -->
{% extends 'inbox/layout.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
<div >
<p>#{{ profile.user.username|upper }}</p>
<div class="buttons has-addons">
{% if profile in user.profile.follows.all %}
<button class="button is-success is-static">Follow</button>
<button class="button is-danger" name="follow" value="unfollow">
Unfollow
</button>
{% else %}
<button class="button is-success" name="follow" value="follow">
Follow
</button>
<button class="button is-danger is-static">Unfollow</button>
{% endif %}
</div>
<p1>following:</p1>
<ul>
{% for following in profile.follows.all %}
<li>{{ following }}</li>
{% endfor %}
</ul>
<p2>followers:</p2>
<ul>
{% for follower in profile.followed_by.all %}
<li>{{ follower }}</li>
{% endfor %}
</ul>
</div>
</form>
{% endblock content %}
profile_list.html template:
<!-- inbox/templates/inbox/profile_list.html -->
{% extends 'inbox/layout.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
{% for profile in profiles %}
<div class="column">
<p>{{ profile.user.username }}</p>
<p>#{{ profile.user.username|lower }}</p>
</div>
{% endfor %}
</form>
{% endblock content %}

You need to match Profile's pk with profile = Profile.objects.get(pk=pk), currently you mentioned the pk of User model, which matched the given queryset in profile view, so try sending pk of profile in profile_list.html template:
{% for profile in profiles %}
<div class="column">
<p>{{ profile.user.username }}</p>
<p>#{{ profile.user.username|lower }}</p>
</div>
{% endfor %}
Also, it is better to use get_object_or_404 instead of get, as it calls get() on a given model manager, but it raises Http404 instead of the model’s DoesNotExist exception.
So, views.py:
def profile(request, pk):
if not hasattr(request.user, 'profile'):
missing_profile = Profile(user=request.user)
missing_profile.save()
profile = get_object_or_404(Profile, pk=pk)
if request.method == "POST":
current_user_profile = request.user.profile
data = request.POST
action = data.get("follow")
if action == "follow":
current_user_profile.follows.add(profile)
elif action == "unfollow":
current_user_profile.follows.remove(profile)
current_user_profile.save()
return render(request, "home/profile.html", {"profile": profile})
Now, if the profile does not exist, it will show no Profile matches the given query.

Related

Django - Simple User Register not working [Not saving to DB]

I have simple user registration page, but its not saving to the database.
Issue: Register form displays, upon clicking submit button, doesn't do anything! Stays there (it should show a HttpResponse('User Registered') And save to db
I've know I'm missing something, but what? ideas please.
Views.py
from django.shortcuts import render
from django.views.generic import CreateView
from website.forms import RegisterUserForm
from django.http import HttpResponseForbidden
# Create your views here.
class RegisterUserView(CreateView):
form_class = RegisterUserForm
template_name = "account/register.html"
# Overide dispatch func - check if the user is authenticated or return forbidden
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated():
return HttpResponseForbidden()
return super(RegisterUserView, self).dispatch(request, *args, **kwargs)
# Overide form valid method behaviour
def form_valid(self, form):
# False commit - don't save to db, locally cleaning users password first
user = form.save(commit=False)
user.set_password(form.cleaned_data['password'])
user.save();
# Change to redirect - later one!
return HttpResponse('User Registered')
def Home(request):
return render(request, 'account/home.html')
Register.html
{% extends 'base.html' %}
{% block title %}
Register
{% endblock %}
{% block head %}
{% load static %}
<link href="{% static 'forms.css' %}" rel="stylesheet">
{% endblock %}
{% block heading %}
<h1>Register</h1>
{% endblock %}
{% block body %}
<div class="bg-contact2" style="background-image: url('images/bg-01.jpg');">
<div class="container-contact2">
<div class="wrap-contact2">
<form class="contact2-form validate-form">
<span class="contact2-form-title">
<h2> Teacher's Register </h2>
</span>
{% csrf_token %}
{{ form.as_p }}
<div class="container-contact2-form-btn">
<div class="wrap-contact2-form-btn">
<div class="contact2-form-bgbtn"></div>
<button class="contact2-form-btn">
Send Your Message
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<!--
<h2>FORM</h2>
<form action="{% url 'register' %}" class="contact2-form validate-form" method="post ">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Register">
</form> -->
{% endblock %}
forms.py
from django import forms
from django.contrib.auth.models import User
class RegisterUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password2 = forms.CharField(widget=forms.PasswordInput)
class Meta:
# Connect to the user model and select which fields we want input for user model
model = User
fields = ['username', 'email']
# Validate password matched / and clean them
def clean_password2(self):
cd = self.cleaned_data
if cd['password2'] != cd['password']:
raise ValidationError("Password don't match")
return cd['password2']
I think you are missing the type in your button tag:
<form method="POST">
<span class="contact2-form-title">
<h2> Teacher's Register </h2>
</span>
{% csrf_token %}
{{ form.as_p }}
<div class="container-contact2-form-btn">
<div class="wrap-contact2-form-btn">
<div class="contact2-form-bgbtn"></div>
<button type="submit" class="contact2-form-btn">
Send Your Message
</button>
</div>
</div>
</form>
form tag should have an attribute action to tell where to take the data of your form to. So in Register.html you should add
action="{% url 'nameofyourviewgiveninurls.py'%}"
in your form tag

not able to open registration form page

trying to create a registration form, and I am facing an issue. so, below are my python pages:
form.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(ModelForm):
class Meta:
model = User
fields = ('username','password','email')
models.py
from django.db import models
#from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
class Registration(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
urls.py
urlpatterns = [
url(r'^register/$', views.SignUpFormView, name= 'register'),
]
test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form }}
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
<input type="submit" value="Submit" />
</form>
{% endblock %}
{% endblock %}
views.py
def SignUpFormView(request):
template_name = 'test.html'
try:
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
email = form.cleaned_data.get('email')
return render(request, template_name, {'form':form})
except ValueError:
print("Oops! That was not a valid entry, try again...")
else:
SignUpForm()
return render(request, 'user_info/about.html')
The issue is, my "SignUpFormView" function in views.py is not entering the "if" statement, its directly going to "else". I seem to be lost here.
I have 'about.html'. I do not see any error as well. Which I find very weird. Please help.
Note: I am using Django's default in-built "User" model, and I do not wish to create any custom model.
Modified views.py
def SignUpFormView(request):
user_form = 'SignUpForm'
template_name = 'test.html'
if request.method == 'POST':
form = user_form(request.POST)
if form.is_valid():
form.save()
#username = form.cleaned_data.get('username')
#password = form.cleaned_data.get('password')
#email = form.cleaned_data.get('email')
#user.save()
return render(request, template_name, {'form':form})
else:
SignUpForm()
return render(request, 'user_info/about.html')
Modified forms.py
from .models import User
from django import forms
from django.forms import ModelForm
class SignUpForm(forms.ModelForm):
#password = forms.Charfield(widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username','password','email')
modified test.html
{% extends 'user_info/base.html' %}
{% block body %}
{% block content %}
{% for error in form.errors %}
{{ form.errors | default_errors }}
{% endfor %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{% for field in form %}
<p>
username:<br>
<input type="text" name="username"><br>
password:<br>
<input type="text" name="password"><br>
email:<br>
<input type="text" name="email"><br>
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit" value="Submit">sign up </button>
</form>
{% endblock %}
{% endblock %}

BootstrapError Parameter "form" should contain a valid Django Form

i have an app called reviews
reviews/forms.py
from django.forms import ModelForm, Textarea
from reviews.models import Review
class ReviewForm(ModelForm):
class Meta:
model = Review
fields = ['rating', 'comment']
widgets = {
'comment': Textarea(attrs={'cols': 40, 'rows': 15}),
}
reviews/views.py
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from .models import Review, Wine
from .forms import ReviewForm
import datetime
from django.contrib.auth.decorators import login_required
#login_required
def add_review(request, wine_id):
wine = get_object_or_404(Wine, pk=wine_id)
form = ReviewForm(request.POST)
if form.is_valid():
rating = form.cleaned_data['rating']
comment = form.cleaned_data['comment']
user_name = form.cleaned_data['user_name']
user_name = request.user.username
review = Review()
review.wine = wine
review.user_name = user_name
review.rating = rating
review.comment = comment
review.pub_date = datetime.datetime.now()
review.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('reviews:wine_detail', args=(wine.id,)))
return render(request, 'reviews/wine_detail.html', {'wine': wine, 'form': form})
reviews/templates/reviews/wine_detail.html
{% extends 'base.html' %}
{% load bootstrap3 %}
{% block title %}
<h2>{{ wine.name }}</h2>
<h5>{{ wine.review_set.count }} reviews ({{ wine.average_rating | floatformat }} average rating)</h5>
{% endblock %}
{% block content %}
<h3>Recent reviews</h3>
{% if wine.review_set.all %}
<div class="row">
{% for review in wine.review_set.all %}
<div class="col-xs-6 col-lg-4">
<em>{{ review.comment }}</em>
<h6>Rated {{ review.rating }} of 5 by {{ review.user_name }}</h6>
<h5><a href="{% url 'reviews:review_detail' review.id %}">
Read more
</a></h5>
</div>
{% endfor %}
</div>
{% else %}
<p>No reviews for this wine yet</p>
{% endif %}
<h3>Add your review</h3>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'reviews:add_review' wine.id %}" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form layout='inline' %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "star" %} Add
</button>
{% endbuttons %}
</form>
{% endblock %}
base.html
{% load bootstrap3 %}
{% bootstrap_css %}
{% bootstrap_javascript %}
{% block bootstrap3_content %}
<div class="container">
<nav class="navbar navbar-default">
<div class="navbar-header">
<a class="navbar-brand" href="{% url 'reviews:review_list' %}">Winerama</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Wine list</li>
<li>Home</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li>Hello {{ user.username }}</li>
<li>Logout</li>
{% else %}
<li>Login</li>
<li>Register</li>
{% endif %}
</ul>
</div>
</nav>
<h1>{% block title %}(no title){% endblock %}</h1>
{% bootstrap_messages %}
{% block content %}(no content){% endblock %}
</div>
{% endblock %}
I am getting the error at the line {% bootstrap_form form layout='inline' %} in the html file
Any idea how to fix this?
There's a few problems with your code as it stands, so I'll try to clean it up with some comments as I would write it to add a review to a wine.
#login_required
def add_review(request, wine_id):
wine = get_object_or_404(Wine, pk=wine_id)
if request.POST:
form = ReviewForm(request.POST)
else:
form = ReviewForm()
if form.is_valid():
### NO NEED FOR - already set as part of valid modelform ::: rating = form.cleaned_data['rating']
### AS WELL AS ::: comment = form.cleaned_data['comment']
### THIS IS NOT A FIELD IN YOUR FORM :::user_name = form.cleaned_data['user_name']
user_name = request.user.username
review = form.save(commit=False) # commit = False means that this instantiate but not save a Review model object
review.wine = wine
review.user_name = user_name # Why use this instead of a ForeignKey to user?
review.pub_date = datetime.datetime.now() # works as long as pub_date is a DateTimeField
review.save() # save to the DB now
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('reviews:wine_detail', args=(wine.id,))) # THIS will redirect only upon form save
return render(request, 'reviews/wine_detail.html', {'wine': wine, 'form': form})
Now, the error your seeing is most likely related to you passing request.POST to a form even if request.POST is blank; the form will attempt to set initial values but with a querydict that has no values that actually relates to the form.
EDIT: In response to your comments, my next step would be to try and render each form field individually and see if I can trigger a failure.
Instead of {% bootstrap_form form layout='inline' %}, try-
{% for field in form %}
{% bootstrap_field field %}
{% endfor %}
If this is an error with the django-bootstrap library trying to render the textarea widget and the inline style together (as I would suspect at this point), you can also eliminate the widget parameter and see if there's a fix. If there is, I'd suggest overriding your modelform's init method for assign a widget post a call super on init.
In Class Base View
This error may occur when you use form_class in the wrong generic view.
⮕ Open your views.py then check to see if you have set the wrong generic view in your class.
Example
class ProfileUpdateView(T̶e̶m̶p̶l̶a̶t̶e̶V̶i̶e̶w̶ UpdateView):
model = User
form_class = forms.ProfileForm
success_url = reverse_lazy("stories:story_list")
template_name = 'profile.html'
def get_object(self, queryset=None):
return get_object_or_404(User, pk=self.request.user.id)

{{ user.get_profile.foo }} not working in Django

I am trying to display user profile information in the users profile (original, I know,) but I can't get it to work unless it's the form view of the profile. I call user and foo in my user profile edit form with {{form.instance.user}} and it works fine.
I've implemented {{ user.get_profile.foo }} in my static user profile template (loggedin.html) but nothing happens.
My static user profile (loggedin.html) template looks like this:
{% extends "base.html" %}
{% block content %}
<title>{% block title %} | {{ username }}{% endblock %}</title>
<h2>Hi, {{ username }}!</h2>
<h3>{{ user.get_profile.foo }}</h3>
Edit Profile
{% endblock content %}
The view for loggedin.html:
def loggedin(request):
return render_to_response('loggedin.html', {'username':request.user.username, 'user':request.user})
My user profile edit form(profile.html) template:
{% extends "base.html" %}
{% block content %}
<title>{% block title %} | Edit Profile{% endblock %}</title>
<h2>Edit {{ username }}</h2>
{% for field in form %}
{{ field.error }}
{% endfor %}
<form action="/accounts/profile/" method="post">{% csrf_token %}
<label for="id_user">Username:</label>
<br>
<input id="id_user" name="user" type="text" value="{{form.instance.user}}">
<br><br>
<label for="id_foo">Foo:</label>
<br>
<input id="id_foo" name="foo" type="text" value="{{form.instance.foo}}">
<br><br>
<input type="submit" value="Update">
</form>
{% endblock content %}
My user profile (form) model:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
foo = models.CharField(max_length=30)
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
My user profile (form) view:
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from forms import UserProfileForm
from django.contrib.auth.decorators import login_required
from userprofile.models import UserProfile
#login_required
def user_profile(request):
user = request.user
username = request.user.username
if request.method == 'POST':
form = UserProfileForm(request.POST, instance=request.user.profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/loggedin')
else:
profile = user.profile
form = UserProfileForm(instance=profile)
args = {}
args.update(csrf(request))
args['form'] = form
args['user'] = user
args['username'] = username
return render_to_response('profile.html', args)
I can get the username and foo value to display fine in the user profile form, but when I try to get the same information to display in the static profile, it doesn't work.
Full disclosure: my static profile is in an app called polls which is different than the userprofile app where my edit form model and template are located, but I'm not sure if that has anything to do with this issue.
If you need to see my urls, settings, or admin code, let me know; I figured it wasn't relevant, and would just add clutter, but I'm happy to add it if needed.
Your property is User.profile. Therefore you should try
{{ user.profile.foo }}
in your template, instead of {{ user.get_profile.foo }}.

Trouble rendering listfield model_form on mongoengine

I am using Flask, mongoengine for a project and I am trying to get basic stuff working from http://docs.mongodb.org/manual/tutorial/write-a-tumblelog-application-with-flask-mongoengine/
After implementing everything from above link I added a new field for "tags" in Post and when I try to create a post, my tags doesn't show a input box.
Any help is appreciated.
My code below
class Post(db.Document):
created_at = db.DateTimeField(default=datetime.datetime.now, required=True)
title = db.StringField(max_length=255, required=True)
slug = db.StringField(max_length=255, required=True)
body = db.StringField(required=True)
views = db.IntField(default=0)
category = db.StringField()
tags = db.ListField(db.StringField(max_length=30))
template
{% macro render(form) -%}
<fieldset>
{% for field in form %}
{% if field.type in ['CSRFTokenField', 'HiddenField'] %}
{{ field() }}
{% else %}
<div class="clearfix {% if field.errors %}error{% endif %}">
{{ field.label }}
<div class="input">
{% if field.type == 'ListField' %}
{% for subfield in field.entires %}
{% if subfield.type == 'StringField' %}
{{ field }}
{% endif %}
{% endfor %}
{% elif field.name == "body" %}
{{ field(rows=10, style="width:360px;") }}
{% else %}
{{ field() }}
{% endif %}
{% if field.errors or field.help_text %}
<span class="help-inline">
{% if field.errors %}
{{ field.errors|join(' ') }}
{% else %}
{{ field.help_text }}
{% endif %}
</span>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
</fieldset>
{% endmacro %}
admin.py
from flask import Blueprint, request, redirect, render_template, url_for
from flask.views import MethodView
from pprint import pprint
from flask.ext.mongoengine.wtf import model_form
from tumblog.auth import requires_auth
from tumblog.models import Post
admin = Blueprint('admin', __name__, template_folder='templates')
class List(MethodView):
decorators = [requires_auth]
cls = Post
def get(self,slug=None):
posts = self.cls.objects.all()
return render_template('admin/list.html', posts=posts)
class delList(MethodView):
decorators = [requires_auth]
cls = Post
def get(self,slug=None):
try:
post = self.cls.objects.get(slug=slug)
post.delete()
except:
pass
return redirect(url_for('admin.index'))
class Detail(MethodView):
decorators = [requires_auth]
def get_context(self, slug=None):
form_cls = model_form(Post, exclude=('created_at', 'views'))
if slug:
post = Post.objects.get_or_404(slug=slug)
if request.method == 'POST':
form = form_cls(request.form, inital=post._data)
else:
form = form_cls(obj=post)
else:
post = Post()
form = form_cls(request.form)
context = {
"post": post,
"form": form,
"create": slug is None
}
return context
def get(self, slug):
context = self.get_context(slug)
return render_template('admin/detail.html', **context)
def post(self, slug):
context = self.get_context(slug)
form = context.get('form')
if form.validate():
post = context.get('post')
form.populate_obj(post)
post.save()
return redirect(url_for('admin.index'))
return render_template('admin/detail.html', **context)
# Register the urls
admin.add_url_rule('/admin/', view_func=List.as_view('index'))
admin.add_url_rule('/admin/create/', defaults={'slug': None}, view_func=Detail.as_view('create'))
admin.add_url_rule('/admin/edit/<slug>/', view_func=Detail.as_view('edit'))
admin.add_url_rule('/admin/delete/<slug>/', view_func=delList.as_view('delete'))
Because list fields may have their own special types for each item, you may need to define custom fields; or you can try to use wtforms.fields.FieldList directly.
It is difficult to say which error you are hitting; you can try to put information into the form for debugging, e.g.
{% for field in form %}
<!-- {{field.type}} {{field.label}} -->
... etc ...
{% endfor %}
Also noticed you had a typo
{% for subfield in field.entires %} <=== did you mean field.entries ?
bounty question:
Unless you define help_text when declaring your field, this will not work as expected:
{{ field.help_text }}
You need to include it when declaring your fields, e.g.
oid = ObjectIdField(..., help_text="object id")

Categories

Resources