Django tutorial: 'polls.Choice' has no ForeignKey to 'polls.Choice'. - python

I got this error when im coding in the second part of the django tutorial, i don't know why, i have the same code that the website.
Django 1.8.3
ERRORS:
<class 'polls.admin.ChoiceInline'>: (admin.E202) 'polls.Choice' has no ForeignKey to 'polls.Choice'.
System check identified 1 issue (0 silenced).
My models.py
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
My admin.py
from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None,{'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
admin.site.register(Choice, ChoiceInline)
admin.site.register(Question, QuestionAdmin)
I really will preciate the help, I really have no idea what is the problem , and want to finish this tutorial

The ChoiceInline has already been included in your QuestionAdmin by setting
inlines = [ChoiceInline].
This means that when you edit a question, you will be able to add, edit and delete that question's choices at the same time.
You are getting the error because of this line:
admin.site.register(Choice, ChoiceInline)
This is invalud, becayse you can't register a model with an Inline. You can only register a model with a ModelAdmin class. To stop the error, simply remove this line from your code.
If you want to edit choices by themselves, you need to define a ChoiceAdmin class and register that.
admin.site.register(Choice, ChoiceAdmin)
Or, if you don't need any customisation, you don't actually need a model admin.
admin.site.register(Choice)

Related

How to resolve Django IntegrityError NOT NULL Constraint Field?

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)

Is there a way to block self-following in Follow model?

My model structure looks like this:
from django.db import models
class Follow(models.Model):
follower = models.ForeignKey('accounts.User', related_name='following',
on_delete=models.CASCADE)
user = models.ForeignKey('accounts.User', related_name='followers',
on_delete=models.CASCADE)
class Meta:
unique_together = (('user', 'follower',),)
def __str__(self):
return f'{self.follower.username} follows {self.user.username}'
I'm looking for something similar to "unique_together" but for the same user.
I know there're possibilities to block it in API but I want it to do it from model level.
You can either:
as the other answer says, override clean() or save() to ensure follower != user,
or if you're using a supported database, you could add a Check constraint to do the same on the database level.
Overriding the save method can do the trick here. In your model save method you can check and raise an exception if both follower and user are same. I don't think you would be able to do it using any constraint as unique_together.
Thanks for the answers but I did it this way.
from django.dispatch import receiver
from django.db import models
from django.db.models.signals import pre_save
from django.core.exceptions import ValidationError
class Follow(models.Model):
follower = models.ForeignKey('accounts.User', related_name='following',
on_delete=models.CASCADE)
user = models.ForeignKey('accounts.User', related_name='followers',
on_delete=models.CASCADE)
class Meta:
unique_together = (('user', 'follower',),)
def __str__(self):
return f'{self.follower.username} follows {self.user.username}'
#receiver(pre_save, sender=Follow)
def check_self_following(sender, instance, **kwargs):
if instance.follower == instance.user:
raise ValidationError('You can not follow yourself')

Django polls app admin like form for users

I have followed the django docs starter app and have added in a login and register system using django.auth. I am looking to make it so that a user who has logged in can create a new poll and link the choices to the question automatically. Just like it is done in the django admin panel (see photo).
In the admin.py, you use admin.TabularInLine and fieldsets but I am not sure how I can do this reuglarly in forms.py or views.py I can't seem to find much in the docs or anywhere else so if someone could get, that would be great..
admin.py
from django.contrib import admin
from .models import Question, Choice
class ChoiceInLine(admin.TabularInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['date_posted']})
]
inlines = [ChoiceInLine]
list_display = ('question_text', 'date_posted', 'was_published_recently')
list_filer = 'date_posted'
admin.site.register(Question, QuestionAdmin)
models.py
from django.db import models
from django.utils import timezone
import datetime
class Question(models.Model):
question_text = models.CharField(max_length=200)
date_posted = models.DateTimeField('Date published')
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.date_posted <= now
was_published_recently.admin_order_field = 'date_posted'
was_published_recently.boolean = True
was_published_recently.short_description = 'Posted recently?'
def __str__(self):
return self.question_text
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=100)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
photo of admin form I would like to replicate
I guess this is what you asking for. If you want to do this on your own, I recommend you to look source code of django admin forms (option 2 in answer). You can start researching from here.

NameError at / name 'article_finish_date' is not defined

So I am trying to create a custom Manager that extends the default one and I am getting an error that for the life of me I cannot fix. I've read all the django docs and can't see what I've done wrong!
ERROR:
NameError at /
name 'article_finish_date' is not defined
Here is my models.py
import datetime
from django.conf import settings
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class ArticleManager(models.Manager):
def get_queryset(self):
return super(ArticleManager, self).get_queryset().filter(article_finish_date==None)
class Article(models.Model):
article_name_text = models.CharField(max_length=200)
article_creation_date = models.DateTimeField('date created')
article_publish_date = models.DateTimeField('date published', null=True, blank=True)
article_finish_date = models.DateTimeField('date finished', null=True, blank=True)
def __str__(self):
return self.article_name_text
actives = ArticleManager()
I have tried filtering by all the different values of the Article model, however the same issue occurs. I have tried both migrated and makemigrations, however no progress has been made.
Many thanks in advance, ask if you need more details!
The error is in this part:
.filter(article_finish_date==None)
Python is trying to evaluate the expression article_finish_date==None, except article_finish_date hasn't been defined yet. Instead, you want to use a single =
.filter(article_finish_date=None)

Django Help: AttributeError: 'module' object has no attribute 'Charfield'

I have seen several similar posts of other attributes found but not this. New to Python and Django- I've done the first part of the several tutorials including Django's "Polls" tutorial and when it gets to the point where I syncdb for my app I invariably get 'AttributeError: 'module' object has no attribute CharField.
In models I have copied exactly as the tutorial says:
from django.db import models
class Poll(models.Model):
question = models.Charfield(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
# Create your models here.
'polls' is also added to installed apps and I'm using sqlite3, windows 7, python 2.7.
Any help very appreciated! (I'm trying very hard to learn!)
That is CharField, with uppercase 'f', and not Charfield as in your code.
I think in forms.py you are using
from django.forms import forms
Please use this
from django import forms
change charfield to:
CharField(max_length = 10)
both C and F should be capitalized
This :
question = models.CharField(max_length=200)
Instead of :
question = models.Charfield(max_length=200)
I have the same error but following code works for me:
from django.db import models
#Create your models here.
class Question(models.Model):
question_text = models.CharField(max_length=100)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
choice_text = models.CharField(max_length = 200)
votes = models.IntegerField(default =0)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
Simply change charfield() to charField() ..
In model Poll, spelling of CharField is not properly formatted. Ie you have written a small letter f inplace of a capital letter F. So, replace Charfield by CharField. You can see the code below:
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published') class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField()
Use this
from django.db import models

Categories