Django polls app admin like form for users - python

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.

Related

Django | formfield_for_manytomany - name display in admin

I am just learning Django, please forgive any ignorance here.
Here's my models.py:
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
admin = models.BooleanField("Admin Status")
class Team(models.Model):
name = models.CharField("Team Name", max_length=20, default="")
admins = models.ManyToManyField(User, related_name="admins")
members = models.ManyToManyField(User, related_name="members")
Here's my admin.py
from django.contrib import admin
from .models import Team, Profile
from django.contrib.auth.models import User
class ProfileAdmin(admin.ModelAdmin):
list_display = ('user', 'admin')
admin.site.register(Profile, ProfileAdmin)
class TeamAdmin(admin.ModelAdmin):
list_display = ('name',)
def formfield_for_manytomany(self, db_field, request, **kwargs):
print(db_field)
if db_field.name == "admins":
kwargs["queryset"] = Profile.objects.filter(admin=True)
return super(TeamAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
admin.site.register(Team, TeamAdmin)
This works perfect, but the admins on my admin page are showing as "Profile object (1)," "Profile object (2)," etc...
What am I doing wrong? Or where do I change the way those display?
It takes the __str__ as names for the object, and by default that uses Model object (pk). You thus can override the __str__, for example with:
class Profile(models.Model):
# …
def __str__(self):
return str(user)

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)

the model field's form disappears in django admin

I have two models, which are User and Record. Each has several fields.
from django.db import models
class User(models.Model):
openid = models.CharField(max_length=20)
nickname = models.CharField(max_length=20,null=True)
def __str__(self):
return self.nickname
class Record(models.Model):
expression = models.CharField(max_length=100)
user = models.ForeignKey(User)
time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.expression
I register them in admin.py
from django.contrib import admin
from .models import User,Record
class RecordAdmin(admin.ModelAdmin):
list_display = ('expression','user','time')
class UserAdmin(admin.ModelAdmin):
empty_value_display = "空"
list_display = ('openid','nickname')
admin.site.register(User,UserAdmin)
admin.site.register(Record,RecordAdmin)
it works well in django admin initially. but one day, the fields of the Record model disppeared. It looks like
.
No field displays. It makes me unable to modify or add the values of the Record model. The other model User works well and all data exists in database. So why?
I think you just have to add on_delete=models.CASCADE in your ForeignKey Field. When you are using this kind of field, you have to specify the comportment when you make an update, a delete or anything else on this field.
So your script should be like this :
class Record(models.Model):
expression = models.CharField(max_length=100)
user = models.ForeignKey(User, on_delete=models.CASCADE)
time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.expression
This is the result :
Edit :
You can also modify null=True by default=null
class User(models.Model):
openid = models.CharField(max_length=20)
nickname = models.CharField(max_length=20,default=null)
def __str__(self):
return self.nickname

How do I delete a field from my Django ModelForm?

I'm trying to hide and delete two fields from showing in a form I created in the Django administration page using ModelForm.
I looked at answers that said I should use the "exclude" meta field, but I don't know why it's not working in my case.
Here is my code:
models.py:
class Activity(models.Model):
type = models.CharField(max_length=50, default="")
title = models.CharField(max_length=200, default="")
description = models.CharField(max_length=500)
owner = models.ForeignKey(User, related_name="owner")
college = models.CharField(max_length=200)
location = models.CharField(max_length=200)
room = models.CharField(max_length=200)
startDate = models.DateTimeField(null=True, blank=True)
endDate = models.DateTimeField(null=True, blank=True)
attendee = models.ManyToManyField(Attendee, related_name="attendees",null=True, blank=True)
volunteer = models.ManyToManyField(Volunteer, related_name="volunteers",null=True, blank=True)
I'm trying to exclude the "attendee & volunteer" fields from displaying in the Django administration form.
In admin.py I have:
from django.contrib import admin
from django import forms
from KSUvity.models import Activity
class ActivityForm(forms.ModelForm):
class Meta:
model = Activity
exclude = ['attendee', 'volunteer',]
class ActivityAdmin(admin.ModelAdmin):
exclude = ['attendee', 'volunteer',]
form = ActivityForm
admin.site.register(Activity, ActivityAdmin)
You have to create an admin.py file in your app and register your models
Follow the instuctions
See the example below
from django import forms
from django.contrib import admin
from myapp.models import Person
class PersonForm(forms.ModelForm):
class Meta:
model = Person
exclude = ['name']
class PersonAdmin(admin.ModelAdmin):
exclude = ['age']
form = PersonForm
admin.site.register(Person, PersonAdmin)
You can use either fields or exclude in one class.
In your app admin field add this code.
app_name/admin.py
from django.contrib import admin
class ActivityAdmin(admin.ModelAdmin):
exclude = ('attendee', 'volunteer',)
You have to use ModelAdmin option to exclude fields from form in Django administration, either ModelAdmin.exclude or ModelAdmin.fields. Below is an example:
class ActivityAdmin(admin.ModelAdmin):
exclude = ('attendee', 'volunteer', )
To make it work, you register model like this:
admin.site.register(Activity, ActivityAdmin)
You add this code to admin.py file.

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

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)

Categories