I’m trying to create a category for each post.
I made another class with the same models.py and in the same class Post I made a category = models.ForeignKey
But it keeps showing me this error when I run the server:
(no such column: Blog_post.category_id)
Ps: I did run the makemigrations and the migrate command.
The tutorial I followed just added the model as it is in models.py but should I also make a function for the views.py or its just a model problem ?
models.py
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Post(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, default="Some random thing")
werkstoffnummer = models.CharField(max_length=100)
def __str__(self):
return self.werkstoffnummer
def get_absolute_url(self):
return reverse("post-detail", kwargs={"pk": self.pk})
views.py
from random import choices
from unicodedata import category
from django import forms
from django.shortcuts import get_object_or_404, render, get_list_or_404, HttpResponse
from django.conf import settings
from django.http import HttpResponse, Http404
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.models import User
from django.views.generic import (ListView, DetailView, CreateView, UpdateView, DeleteView)
from .models import Post, Category
from django.db.models import Q
import pandas as pd
import json
import os
def home(request):
context = {"posts": Post.objects.all()}
return render(request, "Blog/home.html", context)
def werkstoffdaten(request):
context = {"posts": Post.objects.all()}
return render(request, "Blog/werkstoffdaten.html", context)
class PostListView(ListView):
model = Post
template_name = "Blog/werkstoffdaten.html" # <app>/<model>_<viewtype>.html
context_object_name = "posts"
ordering = \["-date_posted"\]
paginate_by = 100
class PostListView(ListView):
model = Post
template_name = "Blog/home.html" # <app>/<model>_<viewtype>.html
context_object_name = "posts"
ordering = \["-date_posted"\]
paginate_by = 100
class UserPostListView(ListView):
model = Post
template_name = "Blog/user_posts.html" # <app>/<model>_<viewtype>.html
context_object_name = "posts"
paginate_by = 100
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get("username"))
return Post.objects.filter(author=user).order_by("-date_posted")
class PostDetailView(DetailView):
model = Post
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = \[
"werkstoffnummer", "werkstoffbezeichnung",
\]
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
fields = \[
"werkstoffnummer", "werkstoffbezeichnung",
\]
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Post
success_url = "/"
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
def Periodic_Table(request):
return render(request, "Blog/Periodic_Table.html")
def user_manual(request):
return render(request, "Blog/user_manual.html")
def about(request):
return render(request, "Blog/about.html", {"title": "About"})
def search_post(request):
if request.method == "POST":
searched = request.POST.get("searched")
posts = Post.objects.filter(
Q(werkstoffnummer=searched) | Q(werkstoffbezeichnung=searched) | Q(gruppe=searched)
)
return render(
request, "Blog/search_post.html", {"searched": searched, "posts": posts}
)
else:
return render(request, "Blog/search_post.html", {})
def download(request, path):
file_path = os.path.join(settings.MEDIA_ROOT, path)
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
response\['Content-Disposition'\] = 'inline; filename=' + os.path.basename(file_path)
return response
raise Http404
OperationalError at /
https://imgur.com/a/lVDedeq
Delete default="Some random thing" in your category field, default value for foreign key of your Category model, must be a private key (pk (aka id (type == integer))), but not the string.
If you just delete this default value, it will work, or you can put default=1 as first object of your Category models would be default for your new Post objects
class Post(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
or
class Post(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=1)
Related
I want that when I try to create a new account, the site_name field is prepopulated with the site that has it
for instance, an account under reddit should have a site_name prepopulated with reddit.com already, instead of having to pick from the list of sites.
Here is my class view for account creating an account:
class AccountCreateView(LoginRequiredMixin, CreateView):
model = Account
template_name = "account_new.html"
fields = (
"site_name",
"username",
"password",
)
The rest of my views:
class HomePageView(ListView):
model = Site
template_name = "home.html"
def get_queryset(self):
try:
return Site.objects.filter(author=self.request.user)
except:
return HttpResponse("Login please!")
class SiteDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView):
model = Site
template_name = "site_detail.html"
def test_func(self):
obj = self.get_object()
return obj.author == self.request.user
class SiteDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Site
template_name = "site_delete.html"
success_url = reverse_lazy("home")
def test_func(self):
obj = self.get_object()
return obj.author == self.request.user
class SiteEditView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Site
template_name = "site_edit.html"
fields = ("siteName",)
def test_func(self):
obj = self.get_object()
return obj.author == self.request.user
class AccountDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Account
template_name = "account_delete.html"
slug_field = "slug_field"
slug_url_kwarg = "slug_field"
success_url = reverse_lazy("home")
class AccountEditView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Account
template_name = "account_edit.html"
fields = (
"username",
"password",
)
slug_field = "slug_field"
slug_url_kwarg = "slug_field"
class SiteCreateView(LoginRequiredMixin, CreateView):
model = Site
template_name = "site_new.html"
fields = ("siteName",)
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
models.py:
from django.db import models
from django.urls import reverse
from django.conf import settings
from django.template.defaultfilters import slugify
class Site(models.Model):
siteName = models.CharField(max_length=200)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
slug = models.SlugField(null=False, unique=True)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.siteName
def get_absolute_url(self):
return reverse("site_detail", kwargs={"slug": self.slug})
def save(self, *args, **kwargs):
if not self.slug:
slug_str = "%s %s" % (self.siteName, self.author)
self.slug = slugify(slug_str)
super(Site, self).save()
class Account(models.Model):
site_name = models.ForeignKey(Site, on_delete=models.CASCADE)
username = models.CharField(max_length=140)
password = models.CharField(max_length=50)
slug_field = models.SlugField(null=False, unique=True)
def __str__(self):
return self.username
def get_absolute_url(self):
return reverse("home")
def save(self, *args, **kwargs):
if not self.slug_field:
self.slug_field = slugify(self.username)
return super().save(*args, **kwargs)
admin.py:
from django.contrib import admin
from .models import Site, Account
class SiteAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("siteName",)}
class AccountAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug_field": ("username",)}
admin.site.register(Site, SiteAdmin)
admin.site.register(Account, AccountAdmin)
A picture of creating a new account under redditcom, still having to specify the site_name:
createaccount picture
How can i do it so the user after editing the post doesn't get redirected to homepage but to the detail view of the post they just edited
My views.py
from . models import Post
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import DeleteView, UpdateView, CreateView
from django.urls import reverse_lazy
def home(request):
posts = Post.objects.all()
return render(request, 'pages/index.html', {'posts':posts})
def detail(request, slug):
post = Post.objects.get(slug=slug)
return render(request, 'pages/detail.html', {'post':post})
class edit(LoginRequiredMixin, UpdateView):
model = Post
template_name = 'pages/edit.html'
fields = ['title','image','body']
success_url = reverse_lazy('pages:homepage')
def dispatch(self, request, *args, **kwargs):
handler = super().dispatch(request, *args, **kwargs)
user = request.user
post = self.get_object()
if post.author != user:
raise PermissionDenied
return handler
my models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.db.models.signals import pre_save
from A_Tech_Blog.utils import unique_slug_generator
class Post(models.Model):
title = models.CharField(max_length=300)
slug = models.SlugField(blank=True, null=True, max_length=300)
image = models.ImageField(upload_to='post_images', default='default.jpg')
time_created = models.DateTimeField(auto_now_add=True)
views = models.IntegerField(default=0)
body = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return f'{self.title} -- Author={str(self.author)}'
class Meta:
ordering = ['-time_created']
verbose_name_plural = 'Posts'
def get_absolute_url(self):
return reverse('pages:detail', args=(self.slug))
def slug_generator(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = unique_slug_generator(instance)
pre_save.connect(slug_generator, sender=Post)
I want to be able to edit the post then get directed to the detail view of the post instead of being redirected to the web app homepage
You can override the get_success_url() method in your view
Something like this should work
class edit(LoginRequiredMixin, UpdateView):
...
# success_url = reverse_lazy('pages:homepage')
def get_success_url(self):
return reverse('pages:detail', args=[self.slug])
I am new on this field and i am currently learning django and i come up with this problem. I am working on a project which is a social clone project and this project you can only post when you are in a group and i've encountered this problem when i post. The first post is working fine but the second post i get this error message called IntegrityError i've tried to delete my migrations and database and migrate and makemigrations again but does not fix the problem and now i am stuck and i hope someone will help me. This is the actual error
Posts Models
##########################
## POSTS MODELS.PY FILE ##
##########################
from django.contrib.auth import get_user_model
from django.db import models
from groups.models import Group
from misaka import html
from django.urls import reverse
from django.conf import settings
User = get_user_model()
class Post(models.Model):
user = models.ForeignKey(User, related_name='posts', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now=True)
message = models.TextField()
message_html = models.TextField(editable=False)
group = models.ForeignKey(Group, related_name='posts', null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return self.message
def save(self, *args, **kwargs):
self.message_html = html(self.message)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse(
'posts:single',
kwargs={
'username': self.user.username,
'pk': self.pk
}
)
class Meta:
ordering = ['-created_at']
unique_together = ['user', 'group']
Posts Views.py
#########################
## POSTS VIEWS.PY FILE ##
#########################
from django.contrib.auth import get_user_model
from braces.views import SelectRelatedMixin
from django.views import generic
from posts import models, forms
from django.http import Http404
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.contrib import messages
User = get_user_model()
class PostList(SelectRelatedMixin, generic.ListView):
model = models.Post
select_related = ('user', 'group')
class UserPost(generic.ListView):
model = models.Post
template_name = 'posts/user_post_list.html'
def get_queryset(self):
try:
self.post_user = User.objects.prefetch_related('posts').get(
username__iexact=self.kwargs.get('username')
)
except User.DoesNotExist:
raise Http404
else:
return self.post_user.posts.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['post_user'] = self.post_user
return context
class PostDetail(SelectRelatedMixin, generic.DetailView):
model = models.Post
select_related = ('user', 'group')
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(
user__username__iexact=self.kwargs.get('username')
)
class CreatePost(LoginRequiredMixin, SelectRelatedMixin, generic.CreateView):
model = models.Post
fields = ('message', 'group')
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return super().form_valid(form)
class DeletePost(LoginRequiredMixin, SelectRelatedMixin, generic.DeleteView):
model = models.Post
select_related = ('user', 'group')
success_url = reverse_lazy('posts:all')
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user_id=self.request.user.id)
def delete(self, *args, **kwargs):
messages.success(self.request, ('Post Delete'))
return super().delete(*args, **kwargs)
Groups Models.py
##########################
## GROUPS VIEWS.PY FILE ##
##########################
from django.contrib.auth import get_user_model
from django import template
from django.db import models
from django.utils.text import slugify
from misaka import html
from django.urls import reverse
from django.conf import settings
User = get_user_model()
register = template.Library()
class Group(models.Model):
name = models.CharField(max_length=255, unique=True)
slug = models.SlugField(allow_unicode=True, unique=True)
description = models.TextField(blank=True, default='')
description_html = models.TextField(editable=False, blank=True, default='')
members = models.ManyToManyField(User, through='GroupMember')
def __str__(self):
return self.name
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
self.description_html = html(self.description)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('groups:single', kwargs={'slug': self.slug})
class Meta:
ordering = ['name']
class GroupMember(models.Model):
group = models.ForeignKey(Group, related_name='memberships', on_delete=models.CASCADE)
user = models.ForeignKey(User, related_name='user_groups', on_delete=models.CASCADE)
def __str__(self):
return self.user.username
class Meta:
unique_together = ('group', 'user')
Groups Views.py
[![##########################
## GROUPS VIEWS.PY FILE ##
##########################
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import generic
from groups.models import Group, GroupMember
from django.urls import reverse
from django.shortcuts import get_object_or_404
from django.db import IntegrityError
from django.contrib import messages
from groups import models
class CreateGroup(LoginRequiredMixin, generic.CreateView):
model = Group
fields = ('name', 'description')
class SingleGroup(generic.DetailView):
model = Group
class ListGroups(generic.ListView):
model = Group
class JoinGroup(LoginRequiredMixin, generic.RedirectView):
def get_redirect_url(self, *args, **kwargs):
return reverse('groups:single', kwargs={'slug': self.kwargs.get('slug')})
def get(self, request, *args, **kwargs):
group = get_object_or_404(Group, slug=self.kwargs.get('slug'))
try:
GroupMember.objects.create(user=self.request.user, group=group)
except IntegrityError:
messages.warning(self.request, (f'Warning, Already A Member Of {group.name}.'))
else:
messages.success(self.request, (f'You Are Now A Member Of {group.name} Group.'))
return super().get(request, *args, **kwargs)
class LeaveGroup(LoginRequiredMixin, generic.RedirectView):
def get_redirect_url(self, *args, **kwargs):
return reverse('groups:single', kwargs={'slug': self.kwargs.get('slug')})
def get(self, request, *args, **kwargs):
try:
membership = models.GroupMember.objects.filter(
user=self.request.user,
group__slug=self.kwargs.get('slug')
).get()
except models.GroupMember.DoesNotExist:
messages.warning(self.request, ("You Can't Leave This Group Because You Aren't In It."))
else:
membership.delete()
messages.success(self.request, ('You Have Successfully Left This Group.'))
return super().get(request, *args, **kwargs)
Remove unique_together from your Post model. It means that only one Post object can have that particular user and model combination, that is why you are getting the integrity error.
The error which you are getting is all about the unique constraint.
unique_together = ['user', 'group']
Since you have defined in your model the unique_together attribute, you need to have unique rows of the combination for user and group. One user can post only once in a group and you are trying to post in the same group by the same user, that's why you are getting a unique constraint failed error.
Hi I'm getting tottaly empty Comments. And I don't really know why.
Here is my view file.
from django.shortcuts import render, redirect
from .forms import PostForm
from django.views.generic import TemplateView
from .forms import CommentForm
from django.shortcuts import get_object_or_404
from .models import Post
class createPost(TemplateView):
template_name = 'forum/createPost.html'
def get(self, request):
form = PostForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = PostForm(request.POST)
if(form.is_valid()):
form.save()
return redirect('/forum')
def add_comment(request, pk):
post = get_object_or_404(Post, pk=pk)
if(request.method == 'POST'):
form = CommentForm(request.POST)
if(form.is_valid()):
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('/forum/')
else:
form = CommentForm()
template = 'forum/addComment.html'
context = {'form': form}
return render(request, template, context)
And here is my models file
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=140)
body = models.CharField(max_length=500)
date = models.DateTimeField()
def __str__(self):
return self.title
class Comment(models.Model):
post = models.ForeignKey(Post, related_name='comments', null=True, on_delete=models.SET_NULL)
com_title = models.CharField(max_length=140)
com_body = models.CharField(max_length=500)
def __str__(self):
return self.com_title
And lastly here is forms
from django import forms
from .models import Post, Comment
class PostForm(forms.ModelForm):
title = forms.CharField(max_length=140)
body = forms.CharField()
date = forms.DateTimeField()
class Meta:
model = Post
fields = ('title', 'body', 'date')
class CommentForm(forms.ModelForm):
title = forms.CharField(max_length=140)
body = forms.CharField(max_length=500)
class Meta:
model = Comment
fields = ('title', 'body')
I don't really know why I'm getting this error. I get a comment but It is totaly blank. Mabye It has something to do with the comment = form.save(commit=False), but i don't know.
I am really new to Django so please let me know if you know how to solve it. Also if there is somthing more I have to add to this question like urls and stuff please let me know.
Thanks ;)
Try changing your view to
class createPost(CreateView):
template_name = 'forum/createPost.html'
model=Post
form_class=PostForm
def form_valid(self, form):
form.save()
return http.HttpResponseRedirect('/forum')
and then form to
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'body', 'date')
PS: If you don't want to make any changes to your form fields, then form_class is not required. You may provide the fields to the View itself.
I am trying to make a website where people can find restaurants and menu items based on their pickiness. Currently I am trying to do it so when I add something to the restaurants through forms I have it associated to an user but when I submit the form I get this error:
IntegrityError
NOT Null constraint failed: restaurants_restaurantlocation.owner_id
Here is my forms.py:
from django import forms
from .models import RestaurantLocation
from .validators import validate_category
class RestaurantCreateForm(forms.Form):
name = forms.CharField()
location = forms.CharField(required = False)
category = forms.CharField(required = False)
def clean_name(self):
name = self.cleaned_data.get("name")
if name == "Hello":
raise forms.ValidationError("This is an invalid name. You stubid boy.")
return name
class RestaurantLocationCreateForm(forms.ModelForm):
#email = forms.EmailField()
#category = forms.CharField(validators = [validate_category], required = False)
class Meta:
model = RestaurantLocation
fields = [
"name",
"location",
"category"
]
def clean_name(self):
name = self.cleaned_data.get("name")
if name == "Hello":
raise forms.ValidationError("This is an invalid name. You stubid boy.")
return name
My models.py:
from django.conf import settings
from django.db import models
from django.db.models.signals import pre_save, post_save
from .utils import unique_slug_generator
from .validators import validate_category
# Create your models here.
User = settings.AUTH_USER_MODEL
class RestaurantLocation(models.Model):
owner = models.ForeignKey(User)
name = models.CharField(max_length=120)
location = models.CharField(max_length=120, null=True, blank=True)
category = models.CharField(max_length=120, null=True, blank=True, validators= [validate_category])
slug = models.SlugField(null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
#property
def title(self):
return self.name #obj.title
def rl_pre_save_reciever(sender, instance, *args, **kwargs):
instance.category = instance.category.capitalize()
if not instance.slug:
instance.slug = unique_slug_generator(instance)
pre_save.connect(rl_pre_save_reciever, sender=RestaurantLocation)
My views.py:
from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.views import View
from django.views.generic import TemplateView, ListView, DetailView, CreateView
from django.utils.datastructures import MultiValueDictKeyError
from .forms import RestaurantCreateForm, RestaurantLocationCreateForm
from .models import RestaurantLocation
# Create your views here
def restaurant_createview(request):
form = RestaurantLocationCreateForm(request.POST or None)
errors = None
if form.is_valid():
# customise
# like a pre save
form.save()
# like a post save
return HttpResponseRedirect("/restaurants/")
if form.errors:
errors = form.errors
template_name = "restaurants/form.html"
context = {"form" : form, "errors" : errors}
return render(request, template_name, context)
def restaurant_listview(request):
template_name = "restaurants/restaurants_list.html"
queryset = RestaurantLocation.objects.all()
context = {
"object_list": queryset
}
return render(request, template_name, context)
class RestaurantListView(ListView):
def get_queryset(self):
slug = self.kwargs.get("slug")
if slug:
queryset = RestaurantLocation.objects.filter(
Q(category__iexact = slug) |
Q(category__icontains = slug)
)
else:
queryset = RestaurantLocation.objects.all()
return queryset
class RestaurantDetailView(DetailView):
queryset = RestaurantLocation.objects.all()
class RestaurantCreateView(CreateView):
form_class = RestaurantLocationCreateForm
template_name = "restaurants/form.html"
success_url = "/restaurants/"
If you need any other piece of code please ask, thank you
Looking at your RestaurantLocation model, you have a foreign key into the User table:
class RestaurantLocation(models.Model):
owner = models.ForeignKey(User)
By default this can't be empty (this is what "NOT null constraint" means). And indeed it looks like your form does not do anything to fill in a restaurant owner, so you will get a database constraint error when you try to commit.
"This is an invalid name. You stubid boy."
Not a very nice thing to say to your users.