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>
Related
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,
})
I am new to Django and Python and would like to attempt the following. Create a dropdown list from the data in a model and save the data in another model. However everytime I render the form, it is invalid and does not display the template, Any help would be greatly appreciated. Please help where I am going wrong.
Models.py:
class Part(models.Model):
category = models.TextField(default = ' ')
def __str__(self):
"""String for representing the Model object."""
return self.category
class UserItem(models.Model):
name= models.CharField(max_length = 50, null=True)
category = models.ForeignKey(Part, on_delete=models.SET_NULL, null=True)
def __str__(self):
"""String for representing the Model object."""
return self.category
Forms.py:
class DropDown(forms.ModelForm):
name = forms.CharField()
parts = forms.ModelChoiceField(queryset=Part.objects.values_list('category', flat=True).distinct())
class Meta:
model = UserItem
fields = ('name', 'category',)
Views.py:
def index(request):
query_results = Part.objects.all()
#part_list = DropDown()
if request.method == 'POST':
form = DropDown(request.POST)
if form.is_valid():
form.save()
return render(request,'index.html', {'query_results': query_results }, {'form': form } )
else:
print("invalid")
print (DropDown.errors)
form = DropDown()
return HttpResponseRedirect(reverse('genre_create') )
In your views.py, update the last return statement to below-
return render(request, "index.html",
{'form': form, 'query_results': query_results})
You can check here
You can infact get rid of the else block -
def index(request):
query_results = Part.objects.all()
if request.method == 'POST':
form = DropDown(request.POST)
if form.is_valid():
form.save()
return render(request,'index.html', {'query_results': query_results }, {'form': form } )
form = DropDown()
return render(request, "index.html",
{'form': form, 'query_results': query_results})
And, just because you have already created form in your python code, you don't need to write htmls for select and other tags. You can refer this link on form rendering options.
I know that there's a lot of similar questions to mine on stackoverflow but none of them fixed my problem.
I have a form with an imagefield which doesn't work as it should redirect to the index page when it succeeds but it doesn't. I can create a payment with that image from the admin panel but the form doesn't work.
models.py
class Payment(models.Model):
Address = models.CharField(max_length=255)
Payment_ID = models.ImageField(upload_to='payproof')
Status = models.CharField(max_length=5, default="X")
Review_result = models.CharField(max_length=255, default="Not yet reviewed")
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created']
def __unicode__(self):
return u'%s'% self.Status
def __str__(self):
return self.Status
views.py
def new_payment(request):
template ='payment.html'
form = PayForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('index')
else:
form = PayForm()
context = {
'form' : form,
}
return render(request, template, context)
forms.py
class PayForm(forms.ModelForm):
Payment_ID = forms.ImageField()
class Meta:
model = Payment
fields = ['Address',
'Payment_ID']
So the problem was simple i was doing request.POST but the img is a file so all what i should of done was add request.FILES
form = PayForm(request.POST, request.FILES or None)
I'm learning django and I'm trying to save the form using POST method and found its working fine, I'M not able to see the saved message in database(form is not submitted)
Models.py
class Post(models.Model):
title = models.CharField(max_length=200)
description = models.TextField(max_length=10000)
pub_date = models.DateTimeField(auto_now_add=True)
slug = models.SlugField(max_length=200, unique=True)
def __unicode__(self):
return self.title
def description_as_list(self):
return self.description.split('\n')
class Comment(models.Model):
title = models.ForeignKey(Post)
comments = models.CharField(max_length=200)
def __unicode__(self):
return '%s' % (self.title)
Forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'description')
editPostedForm = modelformset_factory(Post, PostForm)
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('comments',)
exclude = ('title',)
Views.py
def detail(request, id):
posts = Post.objects.get(id=id)
comments = posts.comment_set.all()
forms = CommentForm
if request.method == 'POST':
form = CommentForm(request.POST, instance=posts)
print form
if form.is_valid():
form.save(commit=False)
form.save()
else:
print form.errors
else:
form = PostForm()
return render(request, "detail_post.html", {'forms':forms,'posts': posts,'comments':comments})
Why is the post message is not being saved. I got status code 200 in console, also i get the entered data, but the form is not being saved...Any help is much appreciated
I think the problem is that your form excludes title field, but it's required according to Comment definition. You need to give the title to comment instance then save it:
def detail(request, id):
posts = Post.objects.get(id=id)
comments = posts.comment_set.all()
forms = CommentForm
if request.method == 'POST':
form = CommentForm(request.POST,instance=posts)
print form
if form.is_valid():
# create a comment instance in memory first
comment = form.save(commit=False)
# fill out the title field
comment.title = posts
comment.save()
else:
print form.errors
else:
form = PostForm()
return render(request, "detail_post.html", {'forms':forms,'posts': posts,'comments':comments})
Also, I don't know why you use plural form for one instance, like posts should be post because you use objects.get(), make your code more readable would save some confusion for other people.
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