I'm very new to Django but I started to create a project and I need some help. My question is very basic but I can't find the right answer.
I made a questionnaire that works fine but I don't know how to do that if a logged in user adds his answers Django associate the answers to the user.
Views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.template import loader
from .models import Stressz_teszt
from .forms import StresszForm
from django.forms import ModelForm
def stressz_item(request):
form = StresszForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('stressz/login.html')
return render(request, 'stressz/stressz-form.html', {'form':form})
Urls.py
from . import views
from django.urls import path
from django.forms import ModelForm
urlpatterns = [
path('', views.index, name='index'),
path('login/', views.login, name='login'),
#stressz teszt form
path('add', views.stressz_item, name='stressz_item'),
path('<int:item_id>/', views.detail, name='detail'),
Forms.py
from django import forms
from django.forms import ModelForm
from .models import Stressz_teszt
class StresszForm(forms.ModelForm):
class Meta:
model = Stressz_teszt
fields = ['stressz_v01', 'stressz_v02', 'stressz_v03', 'stressz_v04', 'stressz_v05',] ...
Models.py
from django.db import models
from django.contrib.auth.models import User
class Stressz_teszt(models.Model):
def __str__(self):
return self.stressz_name
user_name = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
stressz_name = models.CharField(max_length=200)
stressz_company = models.CharField(max_length=300)
stressz_v01 = models.IntegerField()
stressz_v02 = models.IntegerField()
stressz_v03 = models.IntegerField()
stressz_v04 = models.IntegerField()
stressz_v05 = models.IntegerField()
...
Thank you in advance!
You can do it like this :
def stressz_item(request):
if form.is_valid():
stressz_teszt = form.save(commit=False)
stressz_teszt.user_name = request.user
stressz_teszt.save()
return redirect('stressz/login.html')
return render(request, 'stressz/stressz-form.html', {'form': form})
Related
So I simply want when I click on the particular article to output its slug, for example if the slug of the given article is django-rules then i want it to be outputted as django-rules when i click on it. just that
here is my model
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField()
body = models.TextField()
date = models.DateTimeField(auto_now_add = True)
#add in tubnail and author later
def __str__(self):
return self.title
def snippet(self):
return self.body[:50]+'...'
Here is my views.py
from datetime import date
from django.shortcuts import render
from .models import Article
from django.http import HttpRequest
# Create your views here.
def article_list(request):
articles = Article.objects.all().order_by('date')
return render(request,'articles/article_list.html', {'articles': articles} )
def article_detail(request, slug):
return HttpRequest(slug)
url.py
from posixpath import relpath
from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView
from . import views
app_name = 'articles'
urlpatterns = [
path('', views.article_list, name = 'list'),
path('<slug:slug>/', views.article_detail, name = 'detail'),
]
Please dont suggest to add as_view()
its not working.
Instead of return HttpRequest(slug), you need to return HttpResponse(slug).
I'm very new to Django and a bit overwhelmed by the documentation. I think my problem is pretty simple but everything i've found just confused me more.
I am building a little news app with a model NewsItem:
from django.db import models
from django.utils import timezone
# Create your models here.
class NewsItem(models.Model):
title = models.CharField(max_length=50)
newsText = models.TextField()
dateEntered = models.DateTimeField('date entered')
datePublished = models.DateTimeField('date published', blank=True, null=True)
user = models.CharField(max_length=30) #temporary field. will be changed to user foreign key
def __str__(self):
return self.title
def publish(self):
if (self.datePublished == None):
self.datePublished = timezone.now()
def published(self):
return self.datePublished != None
two views (technically 3) index and detail
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.views import generic
from .models import NewsItem
# Create your views here.
class IndexView(generic.ListView):
template_name = 'news/index.html'
context_object_name = 'latestNewsList'
def get_queryset(self):
return NewsItem.objects.order_by('-datePublished')[:5]
#todo
class DetailView(generic.DetailView):
model = NewsItem
template_name = 'news/detail.html'
def publish(request, itemId):
newsItem = get_object_or_404(NewsItem, pk=itemId)
newsItem.publish()
newsItem.save()
return HttpResponseRedirect(reverse('news:detail', args=(newsItem.id,)))
and an urlconf like this
from django.urls import path
from . import views
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:itemId>/publish', views.publish, name='publish'),
]
In the detail view i have a link Publish which just triggers the function views.publish. This view is supposed to redirect back to the detail view.
What i'm trying to do now is to display a little message (like article successfully published) in detail view when it was redirected by the publish view. But i have no idea what would be a good aproach
I could just render the details template in the publish view, but then it would still say news/publish in the URL instead of news/detail
Thanks in advance for your help
Have a look at the messages framework. You could add a success message before redirecting, which will be displayed on the next page.
from django.shortcuts import redirect
from django.contrib import messages
def publish(request, itemId):
newsItem = get_object_or_404(NewsItem, pk=itemId)
newsItem.publish()
newsItem.save()
messages.success(request, "The post has been published")
return redirect('news:detail', newsItem.id)
Note that I've simplified the return statement to use redirect(...) instead of HttpResponseRedirect(reverse(...)).
I have a website made on Django and the users able to leave a review and Ive tried to make it so they can add comments, however they add a comment it just saves it to the database rather then adding it to the post. If anyone knows how I could change my code so that it instead adds the comments to the review that they message on rather then them not appearing on the website at all.
views.py:
from django.shortcuts import render, redirect #Render is used to show the HTML, and redirect is used when the user needs to be sent to a different page automatically.
from .models import Review #This imports the Review database.
from .forms import ReviewForm, CommentForm #This imports the comments and review form.
from django.utils import timezone
from django.contrib.auth.decorators import login_required #This requires the user to be logged in.
def review(request):
return render(request, 'review/review.html')
#login_required(login_url='/accounts/login/')
def review_new(request):
if request.method == "POST":
form = ReviewForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.date = timezone.now()
post.author = request.user
post.save()
return redirect('/review')
else:
form=ReviewForm()
return render(request, 'review/post_edit.html', {'form': form})
def add_comment_to_post(request):
if request.method == "POST":
form = CommentForm(request.POST)
comment = form.save(commit=False)
comment.Review = review
comment.save() #This will save the comment to the database.
return redirect('reivew': review)
else:
form = CommentForm()
return render(request, 'review/add_comment_to_post.html', {'form': form})
models.py:
from django.db import models
from django.conf import settings
from django.utils import timezone
class Review(models.Model):
title = models.CharField(max_length=140)
body = models.TextField(max_length=3000)
date = models.DateTimeField()
author=models.ForeignKey(settings.AUTH_USER_MODEL, `on_delete=models.CASCADE, null=True)`
class comment(models.Model):
review = models.ForeignKey('review.Review', on_delete=models.CASCADE, related_name='comments', null=True)
author=models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
text = models.TextField(max_length=3000)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.text
urls.py:
from django.urls import path, include, re_path
from django.views.generic import ListView, DetailView
from review.models import Review
from . import views
urlpatterns = [
path('', ListView.as_view(
queryset=Review.objects.all().order_by("-date")[:25],
template_name="review/review.html")),
re_path('(?P<pk>(\d+))',DetailView.as_view(model=Review, template_name="review/post.html")),
path('new/', views.review_new, name='review_new'),
path('new/comment', views.add_comment_to_post, name='add_comment_to_post'),
]
I can see that you should change comment.Review = review to something like comment.review = Review.objects.get(id=review_id) where review_id is an id passed from the form. Also notice that your Comment model allows the review to be null, which means currently you are adding comments without linking them correctly to the original post/review they should be related to.
The use case is that a logged in use, can call up their profile into a form, edit it and it gets updated in the database.
With the code below the correct Profile data can be viewed. It can also be called up into an editable form. The form allows the data to be edited , but when it is submitted, the database is NOT updated and the original profile is displayed.
I’ve tried everything, including console print statements so I know that it is getting to the POST portion of the code, is a valid form and doing the initial save().
Any insights would be appreciated (I am using Django 1.11). I do not want to start a rabbit running but the only thing I have not tried is breakink the OneToOne relationship with User and using a foriegnkey because I want the profile entry creaed when the user registers.
Notes:
When I popped this in for testing purposes: save_data.user = request.user
I get the error: Exception Value:'User' object has no attribute 'cleaned_data'`from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
Models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
balance = models.FloatField(default=0)
bank = models.FloatField(default=0)
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
Forms.py
from django import forms
from django.contrib.auth.models import User
from .models import UserProfile
class ProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('description', 'city', 'phone', 'balance', 'bank', 'website', 'image')
Views.py
from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.contrib.auth import login, authenticate, update_session_auth_hash
from django.contrib.auth.forms import (
UserCreationForm,
UserChangeForm,
PasswordChangeForm
)
from django.contrib.auth.models import User
from django.shortcuts import render, redirect
from core.forms import ( EditAccountForm, SignUpForm,
ProfileForm
)
from core.models import UserProfile
from django.views.generic import (TemplateView,ListView,
DetailView,CreateView,
UpdateView,DeleteView)
# Create your views here.
def edit_profile(request):
if request.method == 'POST':
form = ProfileForm(request.POST, instance=request.user)
if form.is_valid():
save_data = form.save()
save_data.user = request.user
print(save_data)
save_data.save()
return redirect(reverse('core:profile'))
else:
udata = UserProfile.objects.get(user=request.user)
form = ProfileForm(instance=udata)
args = {'form': form}
return render(request, 'core/test.html', args)
urls.py
from django.conf.urls import url
from django.contrib import admin
#from playme.core import views as core_views
from core import views as core_views
from django.contrib.auth import views as auth_views
# SET THE NAMESPACE!
app_name = 'core'
urlpatterns = [
url(r'^$', core_views.index, name='index'),
url(r'signup/$', core_views.signup, name='signup'),
url(r'^account/$', core_views.account, name='account'),
url(r'^profile/$', core_views.view_profile, name='profile'),
url(r'^login/$', auth_views.login, {'template_name': 'core/login.html'}, name='user_login'),
url(r'^logout/$', auth_views.logout, {'next_page': '/play/'}, name='logout'),
url(r'^edit_account/$', core_views.edit_account, name='edit_account'),
url(r'^edit_profile/$', core_views.edit_profile, name='edit_profile'),
url(r'^change_password/$', core_views.change_password, name='change_password'),
]
The URL I am hitting is:
http://127.0.0.1:8000/play/profile/
Which then goes to :
http://127.0.0.1:8000/play/edit_profile/
The form loads up but when submitted goes back to:
http://127.0.0.1:8000/play/profile/
With no database update.
I'm surprised this doesn't give an error.
When you instantiate the form on a GET, you correctly pass the UserProfile object as the instance parameter - this is correct because the form has that as its model. But when you instantiate on POST, you incorrectly pass the User object - request.user. You should pass the profile, as you do in the other branch.
Note, in both cases you can get the profile more simply by just doing request.user.userprofile.
Well the form being invalid situation isn't being handled here at all. Your code should look like this
def edit_profile(request):
if request.method == 'POST':
form = ProfileForm(request.POST, instance=request.user)
if form.is_valid():
save_data = form.save(commit=False)
save_data.user = request.user
save_data.save()
return redirect(reverse('core:profile'))
else:
udata = UserProfile.objects.get(user=request.user)
form = ProfileForm(instance=udata)
args = {'form': form}
return render(request, 'core/test.html', args)
Note the change in indentation.
I have a contact form/model in Django that isn't showing up on the admin management page.
I have no idea why it isn't showing up, I have tried to debug by running migrations, and also renaming some of the model variables.
models.py
from django.db import models
class Contact(models.Model):
their_name = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
message = models.CharField(max_length=500)
def __str__(self):
return self.name
forms.py
from django import forms
class ContactForm(forms.Form):
their_name = forms.CharField(label='Name', max_length=100)
email = forms.EmailField(label='Email', max_length=100)
message = forms.CharField(label='Message', max_length=500, widget=forms.Textarea(attrs = {'id': 'Message_form'}))
admin.py
from django.contrib import admin
from .models import Contact
admin.register(Contact)
views.py
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from .models import Contact
from .forms import ContactForm
...
def contact(request):
valid_input = 'no input'
if request.method == 'POST':
valid_input = 'invalid input'
TheForm = ContactForm(request.POST)
if TheForm.is_valid():
valid_input = 'valid input'
name = TheForm['name']
email = TheForm['email']
message = TheForm['message']
Contact.objects.create(name=name, email=email, message=message)
else:
TheForm = ContactForm()
return render(request, 'BlogHome/pages/contact.html', {'TheForm': TheForm, 'valid_input': valid_input})
Could this be the way I am importing the model? I have no idea what is causing this problem.
In your admin.py create an admin class for your Contact model and after register this model in admin using that class.
class ContactAdmin(admin.ModelAdmin):
list_display = ('id', 'their_name', 'email', 'message')
admin.site.register(Contact, ContactAdmin)