Django: Create a Model instance with the build-in User Model fields - python

So i have a Car model. And every car is submitted is assigned to a user. Also every user has his own dashboard where they can submit cars (Only for logged in users).
from django.db import models
from django.contrib.auth.models import User
class Car(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE,null=True)
model_car= models.CharField(max_length=200)
description = models.TextField()
car_image = models.ImageField(null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
This is my forms.py where i create cars. And then i render this form to the frontend.
from django import forms
from django.forms import ModelForm
from tasks.models import Car
class CreateCarForm(ModelForm):
class Meta:
model=Car
fields='__all__'
exclude = ('user',)
Views.py
def create_car(request):
form = CreateCarForm()
if request.method=="POST":
form = CreateCarForm(request.POST,request.FILES)
if form.is_valid():
form.save()
messages.success(request,'Car was Created')
return redirect('create_car')
context={'form':form}
return render(request, 'dashboard/create_car.html',context)
Now it just creates a car instance, but with no selected user. What i would like to do is to create this Car instance, but in the user field, to auto assign the current logged-in user username.
How can i achieve this?

You can set the .user instance of the Car instance wrapped in the CreateCarForm:
from django.contrib.auth.decorators import login_required
#login_required
def create_car(request):
form = CreateCarForm()
if request.method=='POST':
form = CreateCarForm(request.POST,request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
messages.success(request,'Car was Created')
return redirect('create_car')
context={'form':form}
return render(request, 'dashboard/create_car.html', context)

Related

'RegisterForm' object has no attribute 'is_valid'

This Is models.py
from django.db import models
class RegisterForm(models.Model):
fname = models.CharField(max_length=100)
lname = models.CharField(max_length=100)
pno = models.CharField(max_length=100)
email = models.EmailField(max_length=200)
pass1 = models.CharField(max_length=100)
pass2 = models.CharField(max_length=100)
This is my Views.py
from django.shortcuts import render
from .models import RegisterForm
# Create your views here.
def registerView(request):
if request.method=='POST':
fm = RegisterForm(request.POST)
if fm.is_valid():
fname = fm.cleaned_data['fname']
lname = fm.cleaned_data['lanme']
pno = fm.cleaned_data['pno']
email = fm.cleaned_data['email']
pass1 = fm.cleaned_data['pass1']
pass2 = fm.cleaned_data['pass2']
reg = RegisterForm.save(fname = fname,lname=lname,pno=pno,email=email,pass1=pass1,pass2=pass2)
reg.save()
fm = RegisterForm()
else:
fm = RegisterForm()
return render(request, 'register.html', {})
Request Method: POST
Request URL: http://127.0.0.1:8000/
Django Version: 3.2
Exception Type: AttributeError
Exception Value: 'RegisterForm' object has no attribute 'is_valid'
Exception Location: H:\Django\authetication\users\views.py, line 7, in registerView
You created a model, not a form.
Now you need to create forms.py in-app
from django import forms
from .models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = '__all__'
You can use all for all fields in the model but you can put only chosen fields in the form via tuple ('field_name', 'field_name')
Your RegisterForm is a model, not a model form, hence RegisterForm(request.POST) makes no sense, and your RegisterForm has no .is_valid(…) method. A model deals with storing data in the database, whereas a form will receive, validate and clean data.
It looks like you want to define a profile, so you can implement a Profile model:
# app_name/models.py
from django.db import models
class Profile(models.Model):
fname = models.CharField(max_length=100)
lname = models.CharField(max_length=100)
pno = models.CharField(max_length=100)
email = models.EmailField(max_length=200)
pass1 = models.CharField(max_length=100)
pass2 = models.CharField(max_length=100)
and then define a ModelForm based on that model:
# app_name/forms.py
from django import forms
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = '__all__'
Then in the view you can work with:
from django.shortcuts import render
from .forms import ProfileForm
def registerView(request):
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
form.save()
return redirect('name-of-some-view')
else:
form = ProfileForm()
return render(request, 'register.html', {'form': form})
You however should probably make modifications to your model: only use one field where you store the password, and likely the password should be hashed to prevent a data leak in case data of your database got stolen. Django already has a user model, and thre documentation has a section named Customizing authentication in Django. That can help you define a model for a user, and register that user.
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.

Django ModelForm does not save in database

I am trying to make a simple to-do list in Django that each user could have their own task list so when they logged in they add a task and its save for themselves and the list only display their own tasks, but when I try to add a task from the template's form it won't save but when I add task manually from admin panel it work.
my models.py
from django.db import models
from django.contrib.auth.models import User
class Tasks(models.Model):
user = models.ForeignKey(User, null=True,on_delete=models.CASCADE)
title = models.CharField(max_length=200)
check = models.BooleanField(default = False)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
forms.py
from django import forms
from django.forms import ModelForm
from .models import *
class TaskForm(forms.ModelForm):
class Meta:
model = Tasks
fields = '__all__'
views.py:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import *
from .models import Tasks
#login_required(login_url = 'login')
def tasks(request):
tasks = Tasks.objects.filter(user = request.user)
context = { 'tasks': tasks }
return render(request,'ToDo/list.html',context)
#login_required(login_url = 'login')
def add_task(request):
form = TaskForm()
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
form.save(commit=False)
form.user = request.user
form.save()
return redirect('/')
context = {'form' : form}
return render(request,'ToDo/add.html',context)
where is the problem?
You assign the user to the .user attribute of the form, not of the .instance wrapped in the form. You thus should alter the instance with:
#login_required(login_url = 'login')
def add_task(request):
if request.method == 'POST':
form = TaskForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('/')
else:
form = TaskForm()
return render(request, 'ToDo/add.html', {'form' : form})
You should furthermore only redirect in case of a successful POST request: in case the POST request is not successful, the form can render the error messages, and thus will inform the user what the problem is.
Furthermore you make the user field non-editable:
from django.conf import settings
class Tasks(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
editable=False,
on_delete=models.CASCADE
)
title = models.CharField(max_length=200)
check = models.BooleanField(default = False)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Django Modelform doesn't accept selection on POST

The dropdown list appears correctly in the html, However I am unable to figure out why I run into the same error time after time when I try to submit / .
"Select a valid choice. That choice is not one of the available choices."
the problem context
I have two models defined in Django. One CourseModel database to hold all the offered courses and one registration database to link a course to a user.
models.py
from django.db import models
# Create your models here.
class CourseModel(models.Model):
course = models.CharField(max_length=100)
date = models.DateField(max_length=100)
time = models.TimeField()
location = models.CharField(max_length=100)
datetime = models.DateTimeField()
class RegistrationModel(models.Model):
name = models.CharField(max_length=100)
adress = models.CharField(max_length=100)
city = models.CharField(max_length=100)
email = models.EmailField(max_length=100)
course = models.ForeignKey('self', on_delete=models.CASCADE)
def __str__(self):
return self.name
I use modelForm to create a registration form, where the user can subscribe for a course from a dropdown list.
forms.py
from django.forms import ModelForm, RegexField
from home.models import RegistrationModel, CourseModel
from django import forms
import datetime
class RegistrationForm(ModelForm):
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields['course'].queryset = CourseModel.objects.exclude(date__lt=datetime.datetime.today()).values_list('datetime', flat=True)
self.fields['course'].empty_label = None
class Meta:
model = RegistrationModel
fields = '__all__'
views.py
from django.shortcuts import render, redirect
from home.forms import RegistrationForm
from .models import CourseModel
import datetime
def home(request):
return render(request, 'home/home.html')
def registration(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
crs = request.POST.get('course')
print(crs)
if form.is_valid():
cleanform = form.save(commit=False)
cleanform.course = crs
cleanform.save()
return redirect('home')
else:
form = RegistrationForm()
return render(request, 'home/registration.html', {'form': form})
In the RegistrationForm's __init__() method, your self.fields['course'].queryset = ...values_list('datetime', flat=True) returns datetime instances. See values_list() docs.
I believe this may cause the issue. I guess the queryset should return CourseModel instances, based on the Django docs:
ForeignKey is represented by django.forms.ModelChoiceField, which is a ChoiceField whose choices are a model QuerySet.
Also, your RegistrationModel.course field has a foreign key to 'self' instead of the CourseModel. Not sure if that is what you want.
Other examples of setting the field queryset can be found here.

how to fill an author field with current username

I have looked at a lot of different places but none of their solutions work. This is most likely to do them being for older versions of django or my own stupidity. So I am making a blog type of app that for some reason is called reviews instead of blog... anyway I need to automatically fill up an author field with the username of the logged in user. Here is my models.py:
from django.db import models
from django.contrib.auth.models import User
#vars
# Create your models here.
class reviews(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(User, on_delete=models.PROTECT,)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True, blank=True)
and forms.py:
from django import forms
from django.forms import ModelForm
from .models import reviews
from django.contrib.auth.decorators import login_required
class CreatePost_form(ModelForm):
class Meta:
model = reviews
exclude = ['author']
fields = ['title', 'body',]
and views:
from django.shortcuts import render, render_to_response
from .forms import CreatePost_form
from django.http import HttpResponseRedirect
# Create your views here.
def reviewlist(request):
return render
def index(request, ):
return render(request, template_name="index.html")
def CreatePost(request):
form = CreatePost_form(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/reviews/succesfulpost')
return render(request, "reviews/CreatePostTemplate.html", {'form':form})
def succesfulpost(request):
return render(request, "reviews/succesfulpost.html")
def CreatePost(request):
form = CreatePost_form(request.POST)
if form.is_valid():
form.save(commit=False)
form.author = request.user
form.save()
return HttpResponseRedirect('/reviews/succesfulpost')
As simple as that. Rather than actually saving and committing the data, you simply save without committing then you're able to change the value of the excluded field.

How to submit data entered in the forms directly into database?

I have designed a form in django wherein there are 3 fields "Title","Body" & "Tagline". So my query is that when i press submit button after filling up the data that data should be directly inserted into my "notes" database.
Models.py
from django.db import models
class pim(models.Model):
Title = models.CharField(max_length=40)
Body = models.CharField(max_length=40)
TagLine = models.CharField(max_length=40)
Views.py
from django.shortcuts import render_to_response
from django.http import HttpResponse, Http404
def Notes_create(request):
return render_to_response('notesform.html',locals())
You'll need to create a modelform for your pim model:
class pimForm(ModelForm):
class Meta:
model = pim
And your view will have to display the form and handle it when the request type is a POST:
def new(request):
if request.method == 'POST':
form = pimForm(request.POST)
if form.is_valid():
form.save()
return redirect(reverse('your.pim.detail.view', args=[pim.pk]))
else:
form = pimForm()
return render_to_response('notesform.html', {'form': form}, context_instance=RequestContext(request))
Something like that should work

Categories