I tried to build a simple registration from using django, but somehow it does not work
here's my model :
class User(models.Model):
name = models.CharField(max_length=200,unique=True)
email = models.CharField(max_length=200,unique=True)
verified = models.BooleanField(default=False)
voted = models.BooleanField(default=False)
def __str__(self): return self.name
Here is my Form :
class User_data(forms.ModelForm):
class Meta():
form = User
fields = ("name", "email")
Here's my View.py :
def register(response):
form = User_data
if response.method == 'post':
form = User_data(response.POST)
if form.is_valid():
form.save(commit=True)
return index(response)
return render(response,'voting/voting.html', {
'form': form,
})
what did I miss? Thank you
You specify the model fo a ModelForm [Django-doc] with the model attribute in the Meta class, so:
class User_data(forms.ModelForm):
class Meta:
model = User # ← model, not form
fields = ('name', 'email')
Furthermore a successful POST request normally should result in a redirect to implement the Post/Redirect/Get architectural pattern [wiki]:
from django.shortcuts import redirect
def register(request):
form = User_data
if request.method == 'POST': # ← POST, not post
form = User_data(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect(index)
return render(request,'voting/voting.html', {
'form': form,
})
Related
I'm trying to make a Django model based form which will allow to create two models which one will be passed as a foreign key to second one.
models.py
class Recipe(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Ingredient(models.Model):
name = models.CharField(max_length=200)
quantity = models.CharField(max_length=200)
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
def __str__(self):
return self.name
forms
class IngredientForm(ModelForm):
class Meta:
model = Ingredient
fields = ['name', 'quantity']
class RecipeForm(ModelForm):
class Meta:
model = Recipe
fields = ['name']
and views.py ---- here is the problem
def new_recipe_create_view(request, *args, **kwargs):
context = {}
created_recipe = None
form = RecipeForm()
if request.method == 'POST':
form = RecipeForm(request.POST)
if form.is_valid():
print("recipe successfully created")
form.save()
name = form.data['name']
created_recipe = Recipe.objects.filter(name=name).last()
#new recipe is being made correctly
IngredientFormSet = inlineformset_factory(Recipe, Ingredient, fields=('name', 'quantity'), extra=3, max_num=10, labels = {
'name': (''),
'quantity': (''),
})
if request.method == 'POST':
formset = IngredientFormSet(request.POST, instance=created_recipe)
if formset.is_valid():
formset.save()
else:
print("formset is not valid") # <------------------------------------------
else:
formset = IngredientFormSet( instance=created_recipe)
if form.is_valid() and formset.is_valid():
return redirect('index')
context['formset'] = formset
context['form'] = form
return render(request, 'recipes/create_recipe.html', context)
part with inlineformset_factory, I made following docs:
https://docs.djangoproject.com/en/4.1/topics/forms/modelforms/#inline-formsets
chapter: Using an inline formset in a view
but it does not work --> formset.is_valid() is returning False
Where is the Issue ?
It seems like you could be missing the {{formset.management_form}} in the HTML template.
put this as a child to the form tag.
<form ...>
{{form...}}
{{formset..}}
{{formset.management_form}}
</form>
I have been trying to allow staff users to post homework to a database however I keep running into the issue above. I've tried setting data['id'] = 0/'' as well as dropped the table and makemigrations/migrate.
models.py
from django.db import models
from teachers.models import Teacher
class Homework(models.Model):
title = models.CharField(max_length=100)
descripiton = models.CharField(max_length=500)
due = models.DateField()
teacher = models.OneToOneField(
Teacher, null=True, blank=True, on_delete=models.CASCADE)
def __str__(self):
return self.title
form.py
from django import forms
class DateInput(forms.DateInput):
input_type = 'date'
class HomeworkForm(forms.Form):
title = forms.CharField(label='Title', max_length=100)
descripiton = forms.CharField(label='Descripiton', max_length=500)
due = forms.DateField(label='Due', widget=DateInput)
views.py
def homework(request):
if request.user.is_authenticated & request.user.is_staff:
if request.method == 'POST':
data = request.POST.copy()
data['teacher'] = request.user.username
request.POST = data
print(request.POST)
form = HomeworkForm(request.POST)
if form.is_valid():
post = Homework(form)
post.save()
messages.info(request, 'Form sent')
print('worked')
return render(request, 'index/index.html')
else:
print('error in form')
form = HomeworkForm()
return render(request, 'dashboard/setHomework.html', {'form': form})
else:
form = HomeworkForm()
return render(request, 'dashboard/setHomework.html', {'form': form})
else:
return redirect('index')
Did you try data['teacher'] = request.user instead of data['teacher'] = request.user.username ?
You do not need to use request.POST.copy(), request.POST is already a dictionary.
I appreciate the answers. I managed to fix the issue by converting the form to a model form as that form model works better for the situation as the model fields are mapped directly to the inputs.
new forms.py
from homework.models import Homework
from django import forms
class HomeworkForm(forms.ModelForm):
class Meta:
model = Homework
fields = ['title', 'description', 'due']
widgets = {
'due': forms.DateInput(format=('%m/%d/%Y'), attrs={'label': 'due date', 'type': 'date'}),
}
I have a form that is associated with a model, and want to specify the form data using the model's PK to log the response.
However, when I do this, I get the error: QuestionRecordSubmitView() got an unexpected keyword argument 'pk'
urls.py
path('survey/<int:pk>/record_submit_question/', views.QuestionRecordSubmitView, name='survey-question-submit-record')
views.py
def QuestionRecordSubmitView(request):
model = Question
if request.method == 'POST':
form = PostAudio(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('survey-share', kwargs={"pk": form.question}))
else:
form = PostAudio()
return render(request, 'survey/question_audio_submit.html')
models.py
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
response_file = models.FileField(blank=True, upload_to='audio_responses')
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
forms.py
class PostAudio(forms.ModelForm):
class Meta:
model = Choice
fields = ('response_file',)
The view should accept a pk parameter, the primary key that is captured from the path. Furthermore, you should specify the question_id of the instance:
from django.shortcuts import redirect
def QuestionRecordSubmitView(request, pk):
if request.method == 'POST':
form = PostAudio(request.POST, request.FILES)
if form.is_valid():
form.instance.question_id = pk
form.save()
return redirect('survey-share', pk=pk)
else:
form = PostAudio()
return render(request, 'survey/question_audio_submit.html')
The models file:
from django.db import models
from django.conf import settings
class Book(models.Model):
rel_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name="Posted By")
title = models.CharField(max_length=256, verbose_name="Title")
description = models.TextField(verbose_name="Description")
price = models.IntegerField(verbose_name="Price")
state = models.CharField(max_length=256, verbose_name="State")
city = models.CharField(max_length=256, verbose_name="City")
neighbourhood = models.CharField(max_length=256, verbose_name="Neighbourhood")
phone = models.IntegerField(verbose_name="Phone Number")
def __str__(self):
return self.title + f" ({self.rel_user.username})"
The forms file:
from django.forms import ModelForm
from Books.models import Book
class BookForm(ModelForm):
class Meta:
model = Book
fields = ['title', 'description', 'price', 'state', 'city', 'neighbourhood', 'phone']
The views file:
from django.shortcuts import render, redirect
from Books.forms import BookForm
from django.contrib import messages
def sell(request):
if request.method == "GET":
form = BookForm()
else:
form = BookForm(request.POST, )
if form.is_valid():
form.save()
messages.success("Successfully added!")
return redirect('sell')
else:
messages.error("Please fill in all the fields.")
return render(request, 'Books/sell.html', {"form": form})
Every time a user submits the form, I want the ForeignKey's value to be filled with that users model. How do I do this?
So suppose user "John" has filled the form. When he clicks submit, the details he enters + his user model should go into the database for that entry.
def sell(request):
if request.method == "POST":
form = BookForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.rel_user = request.user
instance.save()
messages.success("Successfully added!")
return redirect('sell')
else:
messages.error("Please fill in all the fields.")
else:
form = BookForm()
return render(request, 'Books/sell.html', {"form": form}
request.user can be assigned to rel_user as above
You can assign the user to the instance of the form:
from django.shortcuts import render, redirect
from Books.forms import BookForm
from django.contrib import messages
def sell(request):
if request.method == 'GET':
form = BookForm()
else:
form = BookForm(request.POST)
form.instance.rel_user = request.user
if form.is_valid():
form.save()
messages.success('Successfully added!')
return redirect('sell')
else:
messages.error('Please fill in all the fields.')
return render(request, 'Books/sell.html', {'form': form})
I have a form used to create new posts in a blog, and one of the fields in that form is the owner, which means who is posting it, but that should be taken from login view when user provides his/her login information I don't want the user selecting who is the owner from a list, it should be automatically populated and fixed with his username. I tried different ways, fixing the value on my forms.py but didn't work, it doesn't recognizes the variable. This is my forms.py:
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password')
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('website', 'picture')
class CreatePostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'body','datposted', 'category','owner')
Here is what I have on models:
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
datposted = models.DateTimeField('date posted')
category = models.ForeignKey('Category')
owner = models.ForeignKey('UserProfile')
def __str__(self):
return '%s' % self.title
This is my view:
def create_post(request):
if request.method == 'POST':
form = CreatePostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.datposted = datetime.datetime.now()
#post.owner = request.user()
post.save()
return HttpResponseRedirect('/posts/')
else:
return HttpResponse("Favor. Verifique os campos necessarios")
else:
form = CreatePostForm()
f = {'form' : form}
return render(request,'create_post.html',f)
Could you please help with more details?
I think you just have to remove the 'owner' field from the form and make sure that you handle populating the owner in your view
class CreatePostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'body','datposted', 'category')
view
def create_post(request):
if request.method == 'POST':
form = CreatePostForm(request.POST)
if form.is_valid():
Posts = form.save(commit=False)
# replace below with however you get user profile
Posts.owner = get_user_profile_from_logged_in_user()
Posts.save()
return HttpResponseRedirect('/posts/')
else:
return HttpResponse("Favor. Verifique os campos necessarios")
else:
form = CreatePostForm()
f = {'form' : form}
return render(request,'create_post.html',f)
This case is covered in django docs:
https://docs.djangoproject.com/en/1.7/topics/forms/modelforms/#the-save-method