I am creating a blog with system of comments and tags. Now I faced to a template problem with Model instances. First I put status to all new Posts as "draft" but now I set a the status to 'published' and I got this error message. If you need more code olease tell me.
I tried to watch the behavior of my code when I was adding new elemets to the my code.
models.py
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager,
self).get_queryset()\
.filter(status='published')
class Post(models.Model):
STATUS_CHOICE = (
('draft', 'Draft'),
('published', 'Published')
)
title = models.CharField(max_length=250)
slug = models.CharField(max_length=250,
unique_for_date='publish')
author = models.ForeignKey(User,
on_delete=models.CASCADE,
related_name='blog_posts')
body = models.TextField()
publish = models.DateTimeField(default=timezone.now())
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length=10,
choices=STATUS_CHOICE,
default='published')
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
objects = models.Manager()
published = PublishedManager()
tags = TaggableManager()
def get_absolute_url(self):
return reverse('blog_site:post_detail',
args=[self.publish.year,
self.publish.month,
self.publish.day,
self.slug])
views.py
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post, slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day)
# List of active comment fot this post
comments = post.comments.filter(active=True)
new_comment = None
if request.method == 'POST':
# A comment was posted
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment object bot don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the new comment
new_comment.post = post
# Save the comment to the database
new_comment.save()
else:
comment_form = CommentForm()
return render(request,
'blog_site/post/detail.html',
{'post': post,
'comments': comments,
'new_comment': new_comment,
'comment_form': comment_form})
Template error:
In template Z:\Django\blog\blog_site\templates\blog_site\base.html, error
at line 0
Manager isn't accessible via Post instances
1 : {% load static %}
2 : <html lang="en">
3 : <head>
4 : <meta charset="UTF-8">
5 : <meta name="viewport" content="width=device-width, initial-
scale=1">
6 : <title>{% block title %}{% endblock %}</title>
7 : <link href="{% static "css/blog_site.css" %}" rel="stylesheet">
8 : </head>
base.html
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% endblock %}</title>
<link href="{% static "css/blog_site.css" %}" rel="stylesheet">
</head>
<body>
<div id="pattern"></div>
<div id="header">
<div class="menu" id="logo"><b>#blog</b></div>
<div class="menu" id="nav_bar">
Recently
Best of Month
<a>People</a>
</div>
<div class="menu" id="profile">Profile of user</div>
</div>
<div id="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
Related
I have a model where users save their details. I am able to save user details through the template I have created. But whenever I edit the data to update it, a new entry is created in database
models.py
class User(AbstractUser):
pass
def __str__(self):
return self.username
class Detail(models.Model):
"""
This is the one for model.py
"""
username = models.ForeignKey(User, on_delete=models.CASCADE, null=True, default="")
matricno = models.CharField(max_length=9, default="")
email = models.EmailField(default="")
first_name = models.CharField(max_length=200, default="")
last_name = models.CharField(max_length=255, default="")
class Meta:
verbose_name_plural = "Detail"
def __str__(self):
return self.first_name+ " "+self.last_name
views.py
#login_required(login_url="signin")
def details(request):
form = Details()
if request.method == "POST":
form = Details(request.POST)
if form.is_valid():
detail = form.save(commit=False)
detail.username = request.user
detail.save()
return redirect(success, pk=detail.pk)
else:
form = Details(initial={"matricno":request.user.username})
return render(request, "details.html", {"form":form})
def success(request,pk):
return render(request, "success.html", {"pk":pk})
def updatedetails(request, pk):
detail = Detail.objects.get(id=pk)
form = Details(instance=detail)
if request.method == "POST":
form = Details(request.POST, instance=detail)
if form.is_valid():
form.save()
return redirect(success, pk=detail.pk)
return render(request, "details.html", {"form":form})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("details/", views.details, name="details"),
path("success/<int:pk>/", views.success, name="success"),
path("edit/<int:pk>/", views.updatedetails, name="updatedetails"),
]
The template used for rendering out the form to input user details goes as follows
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>details</title>
</head>
<body>
<form action="/details/" method="POST">
{% csrf_token %}
{% if request.user.is_authenticated %}
<p>
{{form.matricno}}
</p>
<p>
{{form.email}}
</p>
<p>
{{form.first_name}}
</p>
<p>
{{form.last_name}}
</p>
<p>
<input type="submit" value="Create">
</p>
{% endif %}
<div>
<input type="button" value="SignOut">
</div>
</form>
</body>
</html>
After a user enters their details and it is saved to database successfully, it redirect to a success where their is a link that takes you back to the other page to edit the data you inputed and it goes as follows.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Success</title>
</head>
<body>
<h1>Thank You for Filling Out the Form</h1>
<p>Click Here To Edit</p>
</body>
</html>
My problem now is that whenever i click on the link to edit, and i edit the details i have entered, it creates a new entry in database rather than updating previous data.
You need to POST to the edit view, so:
<form action="{% url 'updatedetails' pk=form.instance.pk %}" method="POST">
...
</form>
You should thus make two templates: one to create data, and one to edit data.
I am sorting products by categories. When I am viewing product's details, the program outputs following error:
MultipleObjectsReturned at /default/1/
get() returned more than one Product -- it returned 2!
Users/artemiikhristich/PycharmProjects/Eshop-original/store/views.py, line 114, in product_detail
product = get_object_or_404(Product, slug=slug)
product.html
This template is used for viewing product details
% extends "store/main.html" %}
{% block content %}
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tutorial</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
<!-- CSS -->
<link href="static/css/style.css" rel="stylesheet">
<meta name="robots" content="noindex,follow" />
</head>
<body>
<main class="container">
<!-- Left Column / Headphones Image -->
<!-- Right Column -->
<div class="right-column">
<!-- Product Description -->
<div class="product-description">
<span></span>
<h1>{{product.name}}</h1>
<div class="left-column">
<img data-image="black" src="{{ product.imageURL }}">
</div>
<p>"{{product.description}}"</p>
</div>
<!-- Product Configuration -->
</div>
<!-- Product Pricing -->
<div class="product-price">
<button data-product="{{product.id}}" data-action="add" class="btn btn-outline-secondary add-btn update-cart">Add to Cart</button>
<div class="product-configuration">
How to take the measurements
</div>
</div>
</div>
</main>
<!-- Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" charset="utf-8"></script>
<script src="static/js/script.js" charset="utf-8"></script>
</body>
</html>
{% endblock %}
views.py
Here I have views for product_detail and category_detail
class ProductList(ListView):
model = Product
def product_detail(request, category_slug, slug):
product = get_object_or_404(Product, slug=slug)
context = {
'product': product
}
return render(request, 'store/product.html', context)
def category_detail(request, slug):
category = get_object_or_404(Category, slug=slug)
products = category.products.all()
context = {
'category': category,
'products': products
}
return render(request, 'store/category_detail.html', context)
enter code here
urls.py
from django.urls import path
from . import views
from .views import product_detail, category_detail
urlpatterns = [
# Leave as empty string for base url
path('', views.store, name="store"),
path('cart/', views.cart, name="cart"),
path('checkout/', views.checkout, name="checkout"),
path('update_item/', views.updateItem, name="update_item"),
path('process_order/', views.processOrder, name="process_order"),
path('<slug:category_slug>/<slug:slug>/', product_detail, name='product-detail'),
path('<slug:slug>/', category_detail, name='category_detail')
]
models.py
Here I am linking category and product with foreign key
class Category(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, default=1)
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.title
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE, default=1)
name = models.CharField(max_length=200)
price = models.FloatField()
digital = models.BooleanField(default=False, null=True, blank=True)
image = models.ImageField(null=True, blank=True)
description = models.TextField(null=True, blank=True)
slug = models.SlugField(max_length=255, default=1)
def __str__(self):
return self.name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
Reference
Well your challenge comes from you using get_object_or_404 it would be better to do something like this for your detail view:
def product_detail(request, category_slug, slug):
product = Product.objects.get(slug=slug)
context = {
'product': product
}
return render(request, 'store/product.html', context)
The issue was with the slug field. Previously, in models.py I had:
slug = models.SlugField(max_length=255, default=1)
I have slug field for Product and Category models. Slug is like a unique ID for the product. Previously I said that every time the product is created, the default=1. However, This was not unique as you can imagine. My solution:
slug = models.SlugField(max_length=255, unique=True, default=uuid.uuid1)
I am using unique=True with Universal Unique Identifier library
I hope this helps. Feel free to leave any comments
By entering the phone number in the customer registration form , if the customer already exists then should fill the rest of the fields by fetching it from the backend. if the user does not exists then have to register. help me with the script used for this
this is the model i have.
class Customers(models.Model):
customer_id = models.AutoField(primary_key=True)
cname = models.CharField(max_length=100)
cnumber= models.IntegerField()
caddress= models.CharField(max_length=100)
I m using the modelform here.
class CustForm(forms.ModelForm):
class Meta:
model=Customers
fields = '__all__
this is my view
def customer(request):
form=CustForm()
if request.method=='POST':
form = CustForm(request.POST)
form
if form.is_valid():
form.save(commit=True)
messages.success(request,'successfully customer added')
return render(request,'hello.html')
else:
messages.error(request,'Invalid')
return render(request,'custdata.html',{'form':form})
This is my html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% block content %}
<div>
<center><h2><b>Add Customer</b></h2></center>
<p><form method='post'>
{% csrf_token %}
<center>
{{form.as_p}}
<button type="submit" style="width:200px; height:30px; font-size: 20px;">ADD</button>
</center>
</form>
</div>
{% endblock %}
</body>
</html>```
Colleagues, good afternoon!
There is a model book and a model chapter. Each book has many chapters. Each chapter is tied to a specific book, and if the slug of the chapter is made unique, then when book1 - chapter1, I cannot create book2 - chapter 2, an error is generated. If you make the slug non-unique, then an error is issued that one argument was expected, but 2 was passed.
How can I solve this problem? I want the slug to be a number and django understands that along the path / book1 / 1 / you need to take a slug with number 1, which is tied to book1 specifically, and not to pay attention to the slug with number 1, but tied to book2.
if the slug is unique, then I calmly end up in the right book and the right chapter, but everything collapses when I need to get there as intended.
The path is built like this: / book1 / 1 (chapter) / etc.
book2 / 1 / etc
class Book(models.Model):
some code
class Chapter(models.Model):
book= models.ForeignKey(Book, verbose_name="title", on_delete=models.CASCADE)
number = models.PositiveIntegerField(verbose_name="num chapter")
slug = models.SlugField(unique=True, verbose_name="slug_to", null=True, blank=True)
def save(self, *args, **kwargs):
self.slug = self.number
super().save(*args, **kwargs)
Views.py
class Base(View):
def get(self, request, *args, **kwargs):
book = Book.objects.all()
return render(request, "base.html", context={"book": book})
class BookDetail(DetailView):
model = Book
context_object_name = "book"
template_name = "book_detail.html"
slug_url_kwarg = "slug"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["chapter"] = Chapter.objects.filter(title=self.object)
return context
class ChapterRead(DetailView):
model = Chapter
context_object_name = "chapter"
template_name = "chapter_read.html"
slug_url_kwarg = "int"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["imgs"] = ImgChapter.objects.filter(chapter=self.object)
return context
urls.py
from django.contrib import admin
from django.urls import path
from .views import *
urlpatterns = [
path("", Base.as_view(),name="book_list"),
path("<str:slug>/", BookDetail.as_view(), name="book_detail"),
path("<str:slug>/<str:int>/", ChapterRead.as_view(), name="chapter_detail")
]
html
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tf</title>
</head>
<body>
{% for i in book%}
{{i.name}}
{% endfor %}
</body>
</html>
book_detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ book.name }}
{% for i in chapter %}
{{ i.number }}
{% endfor %}
</body>
</html>
chapter_read.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ chapter.number }}
{% for i in imgs %}
<img src="{{ i.img.url }}">
{% endfor %}
</body>
</html>
I'm making a simple webapp in django where a user can log in , choose one of the given category and post an article under the chosen category. But when I submit my django form to create a new post, it throws me " IntegrityError NOTNULL constraint failed ". I searched many solutions on internet and implemented the same but still it gives me the same error.
Please help me out as to how I fix this bug??
Here are the code snippets:
Models.py
class Category(models.Model):
name = models.CharField(max_length=128,unique=True)
slug = models.SlugField()
def save(self,*args,**kwargs):
self.slug = slugify(self.name)
super(Category,self).save(*args,**kwargs)
def __unicode__(self):
return self.name
class Post(models.Model):
category = models.ForeignKey(Category,null=True,blank=True)
title = models.CharField(max_length=128,null=True,blank=True)
content = models.TextField(blank=True,null=True)
def __unicode__(self):
return self.title
views.py
def index(request):
category_list = Category.objects.all()
context = {'category_list':category_list}
return render(request,'index.html',context)
def category(request,category_name_slug):
context = {}
try:
category = get_object_or_404(Category,slug=category_name_slug)
context['category_name'] = category.name
post = Post.objects.filter(category=category)
context['post'] = post
context['category'] = category
context['category_name_slug'] = category_name_slug
except Category.DoesNotExist:
pass
return render(request,'category.html',context)
#login_required
def create_post(request,category_name_slug):
created = False
instance = get_object_or_404(Category,slug=category_name_slug)
a = Post(category=instance)
if request.method == 'POST':
form = PostForm(request.POST,instance=a)
if form.is_valid():
post = form.save(commit=False)
post.save()
created = True
else:
print form.errors
else:
form = PostForm()
context={
'form':form,
'instance':instance,
'created':created
}
return render(request,"add_post.html",context)
forms.py
from django import forms
from app.models import Post,Category,UserProfile
from django.contrib.auth.models import User
class CategoryForm(forms.ModelForm):
name = forms.CharField(max_length=128, help_text="Please enter category")
slug = forms.CharField(widget=forms.HiddenInput(), required=False)
class Meta:
model = Category
fields = ('name',)
class PostForm(forms.ModelForm):
title = forms.CharField(max_length=128)
content = forms.CharField(widget=forms.Textarea)
class Meta:
model = Post
fields = ('title','content')
exclude = ('category',)
urls.py
from django.conf.urls import url
from django.contrib import admin
from app import views
urlpatterns = [
url(r'^$',views.index,name='index'),
url(r'^about/$',views.about,name='about'),
url(r'^add_category/$',views.add_category,name="add_category"),
url(r'^category/(?P<category_name_slug>[-\w]+)/create_post/$',views.create_post, name='create_post'),
url(r'^category/(?P<category_name_slug>[-\w]+)/$',views.category, name='category'),
url(r'^(?P<id>\d+)/$',views.post_detail,name='post'),
url(r'^register/$',views.register,name="register"),
url(r'^login/$',views.user_login,name="login"),
url(r'^logout/$',views.user_logout,name="logout"),
url(r'^(?P<username>[-\w]+)/$',views.view_profile,name="profile"),
]
templates/add_post.html
<html>
<head>
<title>Create Post</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
</head>
<body>
<h1>Create Post under {{ instance.name }}</h1>
{% if created %}
<strong>Post created successfully</strong>
<a href='/app/'>Home</a>
{% else %}
<form id='post_form' method='post' action='/app/category/{{ instance.slug }}/create_post/' enctype='multipart/form-data'>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="submit" value="Create Post" />
</form>
{% endif %}
</body>
</html>
templates/category.html
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
</head>
<body>
{% if category %}
<h1>{{ category_name }}</h1>
{% if post %}
<ul>
{% for poste in post %}
<li>{{ poste.title }}</li>
{% endfor %}
</ul>
{% else %}
<strong>No posts in this Category</strong>
{% endif %}
{% else %}
<strong>No Category found with {{ category_name }}</strong>
{% endif %}
<a href='/app/category/{{ category.slug }}/create_post/'>Create post</a>
</body>
</html>
It's shows me an error at " post.save() " line in views.py.