django user authentication incorporated with models and views - python

I still cant seem to put a simple program together. I am thinking of a simple program where my coworkers and I could propose a bet with each other. (example: I bet the detriot Lions dont win another game this season) If someone is feeling up to the task of taking that bet they can just hit an accept button. I want the user to be logged in and upon submitting the bet_name and bet_desc of the bet, their username, bet_name, bet_desc, and timestamp is saved to a table. Then a relationship table would save the bet id, win, tie, created_user_id, accepted_user_id, accepted_timestamp, and cancelled. Then userprofile table to keep their username, wins, losses, ties, bets_made, and bets_accepted.
models.py
from django.db import models
from django.contrib.auth.models import User
from datetime import datetime
class UserProfiles(models.Model):
username = models.OneToOneField(User)
wins = models.PositiveIntegerField(default=0)
losses = models.PositiveIntegerField(default=0)
ties = models.PositiveIntegerField(default=0)
bets_made = models.PositiveIntegerField(default=0)
bets_accepted = models.PositiveIntegerField(default=0)
def __str__(self):
return "%s's profile" % self.username
class Bets2(models.Model):
bet_name = models.CharField(max_length=30)
bet_desc = models.CharField(max_length=300)
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
created_user = models.OneToOneField(UserProfiles, primary_key=True)
accepted_user = models.PositiveIntegerField(default=0)
accepted_timestamp = models.DateTimeField(auto_now=True)
win = models.BooleanField(default=True)
tie = models.BooleanField(default=True)
cancelled = models.BooleanField(default=True)
def __str__(self):
return "%s's profile" % self.bet_name
As far as forms.py and views this is all i have so far:
forms.py
from django import forms
from django.core.exceptions import ValidationError
from .models import Bets2, UserProfiles
class BetForm(forms.ModelForm):
class Meta:
model = Bets2
fields = ['bet_name', 'bet_desc',]
def clean_name(self):
bet_name = self.cleaned_data.get('bet_name')
#write code here
return name
def clean_bet(self):
bet_desc = self.cleaned_data.get('bet_desc')
#write code here
return bet
views.py
from django.shortcuts import render
from django.conf import settings
from .forms import BetForm
from .models import Bets2, UserProfiles
def home(request):
title = "2015 Boardbets"
queryset = Bets2.objects.all().order_by('timestamp')
queryuser = UserProfiles.objects.all()
context = {
"title": title,
"queryset" : queryset,
"queryuser" : queryuser,
}
return render(request, "home.html", context)
def boardbet(request):
form = BetForm(request.POST or None)
bet_variables = Bets2.objects.all()
context = {
"form" : form,
"bet_variables" : bet_variables,
}
if form.is_valid():
form.save()
return render(request, "bets.html", context)
This is where i get stumped, i dont know how to incorporate the other two models into the view so that all three tables get created and also how to reference them in the template.
Edit: changed it to one model for Bets

Related

How can I automatically generate unique 4 digits and save in Django Model

I am working on a project in Django where I have a SubmitedApps Model which is intended for all submitted applications. Below is the model code:
class SubmitedApps(models.Model):
applicant = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
application = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
confirm = models.BooleanField()
date = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
self.application == str(uuid.uuid1())
super().save(*args, **kwargs)
def __unicode__(self):
return self.applicant
def __str__(self):
return f'Application Number: {self.application} Username:{self.applicant}'
I also have a ModelForm which is a checkbox as shown below:
class ConfirmForm(forms.ModelForm):
confirm = forms.BooleanField()
class Meta:
model = SubmitedApps
fields = ['confirm']
In the views.py I have try to check if the application was already submitted, and if not it should be submitted else it should redirect the applicant to Application Print Out Slip Page as shown below:
#login_required(login_url='user-login')
def SubmitApp(request):
try:
#Grab the logged in applicant in the submited app table
check_submited = SubmitedApps.objects.get(applicant=request.user)
#If it Does NOT Exist then submit it
except SubmitedApps.DoesNotExist:
if request.method == 'POST':
submit_form = ConfirmForm(request.POST, request.FILES)
if submit_form.is_valid():
submit_form.instance.applicant = request.user
submit_form.save()
messages.success(request, 'WASU 2022 Scholarship Application Submited Successfully')
return redirect('app-slip')
else:
submit_form = ConfirmForm()
context = {
'submit_form':submit_form,
}
return render(request, 'user/confirmation.html', context)
else:
if check_submited.application != "":
return redirect('app-slip')
My problem is that the auto generated output are NOT NUMBERS but cb4f5e96-951e-4d99-bd66-172cd70d16a5 whereas I am looking forward to 4 to 6 Digits Unique Numbers.
you can use UUIDField it's custom and it's from Django model built in ,
import uuid
from django.db import models
class MyUUIDModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
# other fields
and to custom only digit and from 4 to 6 , you can do the following :
import uuid
str(uuid.uuid4().int)[:6]
and finally code will do :
import uuid
from django.db import models
class MyUUIDModel(models.Model):
id = models.UUIDField(primary_key=True, default=str(uuid.uuid4().int)[:6], editable=False)
# other fields
A better idea would be to generate a cryptographic token with the desired length. This also has the possibility of collisions, but I imagine it would be much less than a truncated UUID.
Other Solution:
to use this library:
shortuuid

How to let the user add as many forms as they want to a ModelForm that saves to the same model in django

I have a form to let users make a new poll, it consists of 2 ModelForms one for the Question model and another for the Choice model
a screenshot:
Make new poll form
i want there to be something like a (+) or (add another choice) button where users can add as many choices as they want and then submit it all.
here's the models.py file
models.py
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Question(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=False)
questionText = models.CharField(max_length=150)
datePublished = models.DateTimeField(auto_now_add=True)
def str(self):
return self.questionText
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choiceText = models.CharField(max_length=200)
choiceVotes = models.IntegerField(default=0)
def str(self):
return self.choiceText
forms.py
from django import forms
from .models import Question
from .models import Choice
class NewPollForm(forms.ModelForm):
class Meta:
model = Question
labels = {
"questionText":"Poll question"
}
fields = ("questionText",)
class NewChoicesForm(forms.ModelForm):
class Meta:
model = Choice
labels = {
"choiceText":"Choice"
}
fields = ("choiceText",)
the view for this form's page you can see it is set for only one choice field right now
from .forms import NewPollForm
from .forms import NewChoicesForm
def newpoll(request):
if request.user.is_authenticated == True :
pass
else:
return redirect("users:signup")
if request.method == "POST":
qform = NewPollForm(request.POST)
cform = NewChoicesForm(request.POST)
if qform.is_valid():
newpoll = qform.save(commit=False)
newpoll.user = request.user
newpoll.datePublished = timezone.now()
newpoll.save()
cform.instance.question = newpoll
cform.save()
return redirect("polls:details", pollid=newpoll.pk)
else:
return render (request, "polls/newpoll.html", {"qform":qform, "cform":cform})
else:
qform = NewPollForm()
cform = NewChoicesForm()
return render (request, "polls/newpoll.html", {"qform":qform, "cform":cform})

Django ImportError: cannot import name 'ModelForm'

I am pretty much new for Django and trying to create fields to add a new movie to the existing model. It shows an error : ImportError: cannot import name 'ModelForm'
#forms.py file:
from django import forms
from django import ModelForm
from .models import Movie
class MovieForm(ModelForm):
class Meta:
model = Movie
fields = ['genre', 'price', 'rent_time', 'flag']
class CustForm(forms.Form):
f_name = forms.CharField(label='First_Name', max_length=50)
l_name = forms.CharField(label='Last_Name', max_length=50)
address = forms.CharField(label='Address', max_length=125)
cell = forms.IntegerField(label='Cell')
#------------------------------------------------------------------------
#models.py file:
from django.db import models
from django.forms import ModelForm
class Customer(models.Model):
f_name = models.CharField(max_length=50)
l_name = models.CharField(max_length=50)
address = models.CharField(max_length=125)
cell = models.IntegerField(blank=True, null=True)
class Movie(models.Model):
genre = models.CharField(max_length=50)
price = models.FloatField(blank=True, null=True)
rent_time = models.DateTimeField(auto_now_add=True, blank=True)
flag = models.BooleanField(default=True)
user_id = models.ForeignKey('Customer', on_delete=models.SET_NULL,
null=True)
#------------------------------------------------------------------------
#views.py file:
from django.shortcuts import render
from .models import Customer, Movie
# from django.http import HttpResponseRedirect
from .forms import MovieForm, CustForm
def dashboard(request):
customer_data = Customer.objects.all()
context = {'Customer_List': customer_data}
return render(request, 'movie_renting_app/home.html', context)
def movie_list(request):
movie_data = Movie.objects.all()
context = {"Movie_List": movie_data}
return render(request, 'movie_renting_app/all_movies.html', context)
def rented_movies(request):
rented_movie = Movie.objects.filter(flag=True)
context = {"Rented_Movies_List": rented_movie}
return render(request, 'movie_renting_app/rent.html', context)
def add_movies(request):
if request.POST:
form = MovieForm()
print(request)
# return movie_list(request)
else:
form = MovieForm()
return render(request, 'movie_renting_app/new_movie.html',
{'form': form})
def add_customer(request):
if request.POST:
form = request.POST
print(request)
c = Customer(f_name=form['f_name'], l_name=form['l_name'],
address=form['address'], cell=form['cell'])
c.save()
return dashboard(request)
else:
form = CustForm()
return render(request, 'movie_renting_app/new_customer.html',
{'form': form})
def update_customer_info(request):
pass
def available_list(request):
pass
I am getting an error on command prompt.
I have no clue what is going wrong with my code. I have tried various ways to import the ModelForm but it showing me the same error message. I am using Django 2.0 and Python 3.6
ModelForm class is located in Django forms
so you can import it as shown below.
from django.forms import ModelForm
or use it directly when subclassing your form class
class CustomForm(forms.ModelForm):
# your form fields here
pass
for more information about ModelForms see django docs
The error is probably your second line in forms.py. ModelForm is in django.forms, and can't be imported from django. Try this instead:
from django.forms import ModelForm
Or, change class MovieForm(ModelForm): to class MovieForm(forms.ModelForm): and remove your ModelForm import line.
Replace this wrong code in line 2, "forms.py":
from django import ModelForm # Line 2, "forms.py"
With this correct code:
from django.forms import ModelForm # Line 2, "forms.py"

ForeignKey Error at Django

i spend a lot of hours searching for such an error but didn't found anything,
as you know Djangov2.00 requires you to set on_delete=*** with ForeignKey and here i can't do a ForeignKey anymore.
my Models.py
from django.db import models
class makereport(models.Model):
Name = models.CharField(max_length=50)
VID = models.IntegerField()
Callsign = models.CharField(max_length=6)
Date = models.DateField(default='yy-mm-dd')
SelectAward = models.CharField(max_length=50, choices=(('1', 'Division Online Day'), ('2', 'Pilot Event'), ('3', 'ATC Event'), ('4', 'Pilot Event')))
done = models.ForeignKey('reports', on_delete=models.CASCADE)
# reports.ATC = reports.ATC + 1
def __str__(self):
return self.Name
class reports (models.Model):
Name = models.CharField(max_length=50)
VID = models.IntegerField()
DivisionOnline = models.IntegerField(default=0)
ATCEvent = models.IntegerField(default=0)
PilotEvent = models.IntegerField(default=0)
PilotSupport = models.IntegerField(default=0)
ATC = 0
def __str__(self):
return self.Name
and the Error
django.db.utils.IntegrityError: Not Null constraint failed: report_makereport.done_id
i don't know what to do with that id ,versions before V2 was working.
Views.py
from django.db import IntegrityError
from django.http import HttpResponse, request
from django.shortcuts import render, redirect
# Create your views here.
from django.views import View
from report import models
from report.forms import RepForm
from report.models import makereport, reports
class home(View):
def get(self,request):
form = RepForm()
reps = reports.objects.all()
rep = makereport.objects.all()
context = {
'rep':rep,
'form' : form,
'reps':reps
}
return render(request,'home.html',context)
def post(self,request):
form = RepForm(request.POST)
if form.is_valid():
repo = makereport()
repo.Name = form.cleaned_data['Name']
repo.VID = form.cleaned_data['VID']
repo.Callsign = form.cleaned_data['Callsign']
repo.Date = form.cleaned_data['Date']
repo.SelectAward = form.cleaned_data['SelectAward']
repo.done = None
try:
repo.save()
return redirect('/')
except IntegrityError:
context = {'form':form,
'error_msg': 'Error,Please Check your Information'}
return render(request, 'home.html', context)
else:
return self.get(request)
The way you set up this field done = models.ForeignKey('reports', on_delete=models.CASCADE) means that this field can't remain empty nor null.
When you createe a makereport object, this field must have a report instance, if not IntegrityError: Not Null will raise
In case of creating makereport object without a report instance. the following can do it
done = models.ForeignKey('reports',
on_delete=models.SET_NULL,null=True,blank=True)
in your views, try this:
''' codes '''
repo.done = None
repo.save()

How can I render a ManyToManyField as checkboxes?

I'm making a game link site, where users can post links to their
favorite web game.
When people post games they are supposed to check what category the
game falls into.
I decided to allow many categories for each game since some games can
fall into many categories.
So the question is, how do I handle this in my view?
And how can I show it as Checkboxes, where at least one has to be
checked?
And how can I show this as checkboxes in the Admin as well?
Here is the code
Models:
class Category(models.Model):
category = models.CharField(max_length=200)
def __unicode__(self):
return self.category
class Game(models.Model):
name = models.CharField(max_length=200)
url = models.CharField(max_length=200)
poster = models.ForeignKey(User, related_name='game_poster_set')
postdate = models.DateTimeField(default=datetime.now)
cats = models.ManyToManyField(Category)
hits = models.IntegerField(default=0)
post = models.BooleanField(default=False)
Views:
def submit(request):
form = GameForm(request.POST or None)
if form.is_valid():
game = form.save(commit=False)
game.poster = request.user
game.save()
next = reverse('gamesite.games.views.favorites')
return HttpResponseRedirect(next)
return render_to_response(
'games/submit.html',
{'form': form},
context_instance = RequestContext(request),)
Forms:
class GameForm(forms.ModelForm):
name = forms.CharField(max_length=15, label='Name')
url = forms.URLField(label='URL', initial='http://')
class Meta:
model = Game
fields = ('name','url')
Thanks!
class GameForm(forms.ModelForm):
name = forms.CharField(max_length=15, label='Name')
url = forms.URLField(label='URL', initial='http://')
cats = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=True)
class Meta:
model = Game
fields = ('name','url','cats')
that should fix your view, but i'm not sure about the admin. still looking... will edit if i find anything.
Here is how I solved it (Edit: and the admin thing)
Forms:
cats = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Category.objects.all())
(It was the queryset part I couldn't find..)
View:
cats = form.cleaned_data['cats']
game.cats = cats
And that's all the code needed to save the data.
Edit:
here is a solution for the admin
Models:
from django.contrib import admin
from django.forms import CheckboxSelectMultiple
class MyModelAdmin(admin.ModelAdmin):
formfield_overrides = {
models.ManyToManyField: {'widget': CheckboxSelectMultiple},
}
Admin:
from gamesite.games.models import Game, MyModelAdmin
admin.site.register(Game, MyModelAdmin)
It's kind of quirky in looks, but works!
If someone finds a way to make it more "clean" please post!
Cheers!
Found this on from Chase Seibert, Engineering Manager of Dropbox
Source from Chase Seibert
from django.db import models
from django.forms.models import ModelForm
from django.forms.widgets import CheckboxSelectMultiple
class Company(models.Model):
industries = models.ManyToManyField(Industry, blank=True, null=True)
class CompanyForm(ModelForm):
class Meta:
model = Company
fields = ("industries")
def __init__(self, *args, **kwargs):
super(CompanyForm, self).__init__(*args, **kwargs)
self.fields["industries"].widget = CheckboxSelectMultiple()
self.fields["industries"].queryset = Industry.objects.all()

Categories

Resources