How to resolve Django IntegrityError NOT NULL Constraint Field? - python

I'm building an online judge in which I have a Question model and an Answer model.
models.py
from django.db import models
from django.core.validators import FileExtensionValidator
from django.urls import reverse
class Question(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
solution = models.FileField(
validators=[FileExtensionValidator(allowed_extensions=['txt'])], upload_to= 'media')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('coder:detail', kwargs={'pk': self.pk})
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
result = models.CharField(max_length=100,default = 'answer', null = True, blank = True)
# result = models.FileField( null= True, blank=True, default = 'media/media/output.txt',
# validators=[FileExtensionValidator(allowed_extensions=['txt'])], upload_to= 'media')
def __str__(self):
return f'{self.question.title} Answer'
def get_absolute_url(self):
return reverse('coder:detail', kwargs={'pk': self.pk})
views.py
from django.shortcuts import get_object_or_404, render
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic import ListView, DetailView, CreateView, UpdateView, RedirectView
from django.db.models import Q
from .models import Question, Answer
class CoderListView(ListView):
model = Question
template_name = "coder/coder_list.html"
context_object_name = 'question'
class CoderDetailView(DetailView):
model = Question
template_name = "coder/coder_detail.html"
class CoderCreateView(CreateView):
model = Answer
fields = ['result']
context_object_name = 'answer'
success_url = reverse_lazy('coder:list')
template_name = "coder/coder_form.html"
def form_valid(self, form):
return super().form_valid(form)
What exactly am I doing wrong here?
I was trying out FileField earlier but when I kept getting an error, I tried CharField after flushing the database to debug further but I kept getting this error:
And yes, I did try out setting null, blank, and default values appropriately but still no luck. Maybe something to do with a signals.py file? Or maybe I'm implementing the Foreign key wrong, whatever it is that I'm doing wrong I'm unable to point out at the moment. Help with that would be appreciated.
This page is using CoderCreateView.

I believe this is what caused the problem:
class CoderCreateView(CreateView):
model = Answer
fields = ['result']
context_object_name = 'answer'
For the answer model, you forget to pass in the primary key/object (whichever way you prefer) of the question that the answer is linked to, as in this line in your models.py:
question = models.ForeignKey(Question, on_delete=models.CASCADE)

Related

IntegrityError at /post/new/ NOT NULL constraint failed: blog_post.author_id

Iam trying to learn django but this thing is stopping me from doing that
this is my views.py
from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.http import HttpResponse
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from .models import Post
# Create your views here.
def home(request):
context = {
'posts' : Post.objects.all
}
return render(request,'blog/home.html',context)
class PostListView(ListView):
model = Post
template_name = 'blog/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
# <app>/<model><viewtype>.html
class PostDetailView(DetailView):
model = Post
class PostCreateView(LoginRequiredMixin,CreateView):
model = Post
fields = ['title','content']
class PostUpdateView(LoginRequiredMixin,UpdateView):
model = Post
fields = ['title','content']
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,CreateView):
#LoginRequiredMixin, UserPassesTestMixin,DeleteView
#LoginRequiredMixin, AuthorMixin, ListView
model = Post
success_url = '/'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
else:
return False
def about(request):
return render(request,'blog/about.html',{'title':'About'})
this is my models.py in app directory:
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk':self.pk})
Please help me to solve this bug Iam a self taught web developer and Please give me some advice to learn django framework in python this is really stopping me from achiving my goals and this is lagging my valuable time
Your PostCreateView creates instances of Post and you have set fields = ['title','content'] meaning only these fields would show up in the form. But you have a field author which is non-nullable and without a default, hence you need to set a value for this field too. If you want to set it to the current logged in user you can override the form_valid method of the form and do it there (You already seem to be doing this in PostUpdateView?):
class PostCreateView(LoginRequiredMixin,CreateView):
model = Post
fields = ['title','content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)

Blog on Django, querysets for fetch logged in user's posts

I'm building a blog on Django and know i have to make a personal page for see all the posts published by the user we're logged in now.
I'm using some querysets so.
Her my code
my models.py
from django.db import models
from django.conf import settings
from django.utils import timezone
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)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
Here my forms.py
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User
from .models import Post
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username','email','password1','password2','user_permissions','is_staff','date_joined']
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'text', 'author']
And that's the view which is gonna filter the posts in base of the logged user
from django.contrib.auth.models import User
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from django.utils import timezone
from .forms import CreateUserForm
from .models import Post
from .forms import PostForm
def user_data(request, pk):
user_data = User.objects.get(pk=pk)
posts = user_data.post_set.filter(author=user_data)
context = {'user_data':user_data, 'posts':posts}
return render(request, 'account/user_data.html', context)
#So it returns me just the user data like name, email or date_joined but not his posts
This should give you posts of logged in users from your view
def user_data(request, pk):
posts=Post.objects.filter(author=request.user)
context = {'posts':posts}
return render(request, 'account/user_data.html', context)

different queryset based on permissions in Django Rest Framework

I have seen this link, but I didn't find anything related to my question helping it being resolved.
Imagine we have to create a blog, in which posts have two status:
is_draft
published (published == !is_draft)
So, each user should see all of his/her posts, whether it is draft or not. In addition, Other users should see the published posts of rest of the users.
I am using viewsets in django and I know that we should have different queryset based on the current user permissions but I don't know how.
models.py:
from django.db import models
# Create your models here.
from apps.authors.models import Author
class Post(models.Model):
author = models.ForeignKey(
Author,
related_name="posts",
on_delete=models.CASCADE,
)
title = models.TextField(
null=True,
blank=True,
)
content = models.TextField(
null=True,
blank=True,
)
is_draft = models.BooleanField(
default=True
)
views.py:
from django.shortcuts import render
from rest_framework import viewsets, permissions
# Create your views here.
from apps.posts.models import Post
from apps.posts.serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
def get_permissions(self):
if self.action == "create":
self.permission_classes = [permissions.IsAuthenticated]
elif self.action == "list":
pass #I don't know how can I change this part
return super(PostViewSet, self).get_permissions()
serializers.py:
from rest_framework import serializers
from apps.posts.models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'
Change your queryset like this in your viewset. That way, only your desired posts will be accessed/permitted by the view:
from django.shortcuts import render
from django.db.models import Q
from rest_framework import viewsets, permissions
# Create your views here.
from apps.posts.models import Post
from apps.posts.serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
serializer_class = PostSerializer
def get_permissions(self):
if self.action == "create":
self.permission_classes = [permissions.IsAuthenticated]
return super(PostViewSet, self).get_permissions()
def get_queryset(self, *args, **kwargs):
current_user = self.request.user
current_author = Author.objects.get(user=current_user) #assuming your author class has foreign key to user
return Post.objects.filter(Q(author=current_author) | Q(is_draft=False))

URL Redirection is not working (Django 3.0)

I am the newbie of writing programming, now I am learning django.
I have a problem for URL redirection. I create the model and it does work at admin site.
Also I set the PK for each article, that successfully generate the URL by PK.
However when I post the message form the front-end, after posting it appear the error message suppose it should be redirect to the page of DetailViewand
I have imported the reverse function in my model, but it seem not working.
My python version : 3.7.6 and django version : 3.0.0
ImproperlyConfigured at /add/
No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.
My View
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView
from .models import Page
class PageListView(ListView):
model = Page
template_name='home.html'
context_object_name = 'all_post_list'
class PageDetailView(DetailView):
model = Page
template_name='post.html'
class PageCreateView(CreateView):
model = Page
template_name='post_new.html'
fields = ['title', 'author', 'body', 'body2']
Model
from django.urls import reverse
from django.db import models
from ckeditor.fields import RichTextField
class Page(models.Model):
title = models.CharField(max_length=50)
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
)
body = RichTextField()
body2 = models.TextField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', args=[str(self.id)])
URL
from django.urls import path
from .views import PageListView, PageDetailView, PageCreateView
urlpatterns = [
path('add/', PageCreateView.as_view(), name='post_new'),
path('', PageListView.as_view(), name='home'),
path('blog/<int:pk>/', PageDetailView.as_view(), name='post'),
]
Thanks for helping. :)
I think your indentation is the problem here. Fix it by:
class Page(models.Model):
title = models.CharField(max_length=50)
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
)
body = RichTextField()
body2 = models.TextField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', args=[self.id])

how to use slug to form urls

my models.py file looks like this
from django.db import models
from django.template.defaultfilters import slugify
class Entertainmentblog(models.Model):
slug = models.SlugField(max_length=100)
body = models.TextField()
posted = models.DateTimeField('date published')
img_url0 = models.CharField(max_length=100)
img_alt0 = models.CharField(max_length=100)
title1 = models.CharField(max_length=100)
title2 = models.CharField(max_length=100)
def save(self):
super(Entertainmentblog, self).save()
self.slug = '%i-%s' % ( self.id, slugify(self.slug) )
super(Entertainmentblog, self).save()
And my app urls.py file looks like this
from django.conf.urls import patterns, url
from entertainment import views
urlpatterns = patterns('',
url(r'^$', views.ListView.as_view(), name='index'),
url(r'^(?P<slug>[^\.]+),(?P<id>\d+)/$', views.DetailView.as_view(), name='article'),
)
But this gives an error.
Exception Value: Reverse for 'article' with arguments '(u'what-is-happening',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'entertainment/(?P[^\.]+),(?P\d+)/$']
My view.py file
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views import generic
from entertainment.models import Entertainmentblog
class ListView(generic.ListView, slug, id):
template_name = 'entertainment/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
return Entertainmentblog.objects.order_by('-posted')[:25]
class DetailView(generic.DetailView):
model = Entertainmentblog
template_name = 'entertainment/article.html'
How do I correct this?
Oh, there is serious problems with your views:
First:
class ListView(generic.ListView, slug, id)
should be
class ListView(generic.ListView)
see python inheritance.
Second:
slug and id must be class members of your view so you can redefine you view like this:
class ListView(generic.ListView):
template_name = 'entertainment/index.html'
context_object_name = 'latest_article_list'
slug = None
id = None
def get_queryset(self):
return Entertainmentblog.objects.order_by('-posted')[:25]
Third:
Youre naming a derivate class as its parent. I don't know the implications of doing this, but surely, isn't a good practice.
Finally:
The error you're getting is becouse the view returned by views.DetailView.as_view() (remember DetailView is your derived class) don't receives the arguments you are passing through url. Check your url, I can see in the error that is complaining about and argument (u'what-is-happening',) but there is no id. It should be something like, for example, (u'what-is-happening', '4')

Categories