i am finding a problem in saving the user posts from my Django site. Whenever I try to run the submit form, it shows that the form has been submitted but I cant see the post being saved in the data base.
def addPost(request):
form = hacksform(request.POST or None, request.FILES or None)
if request.method == 'POST':
form = hacksform(request.POST or None, request.FILES or None)
if form.is_valid():
try:
newpost = form(commit= False)
image = request.FILES['photo']
newpost.author = request.user
newpost.post_image = image
newpost.save()
newpost.save_m2m()
except:
newposts = form(commit=False)
newpost.author = request.user
newposts.save()
newposts.save_m2m()
return HttpResponseRedirect('/tweaks/tweaks')
return HttpResponseRedirect('/tweaks/tweaks')
and here is my forms.py file
class hacksform(forms.ModelForm):
VIEW_CHOICES = (
("Option", "Choose Option"),
("Public", "To Public"),
("Channels", "To Channels"),
)
title = forms.CharField(widget=forms.TextInput(attrs={'class': 'user-title', 'placeholder': 'Title'}) ,required=True)
content = forms.CharField(widget=forms.Textarea(attrs={'class': 'user-text', 'placeholder': 'Questions'}) ,required=False)
tags = forms.CharField(widget=forms.TextInput(attrs={'class': 'input-tag', 'placeholder': 'Add Tag'}) ,required=False)
audience_privacy = forms.CharField(widget=forms.Select(choices=VIEW_CHOICES,attrs={'id': 'selector'}) ,required=False)
class Meta:
model = hacks
fields = [
'title',
'author',
'tags',
'content',
'post_image',
'audience_privacy'
]
any ideas why I cant post
def addPost(request):
if request.method == 'POST':
form = hacksform(request.POST or None, request.FILES or None)
if form.is_valid():
try:
newpost = form(commit= False)
image = request.FILES['photo']
newpost.author = request.user
newpost.post_image = image
newpost.save()
newpost.save_m2m()
except:
newposts = form(commit=False)
newpost.author = request.user
newposts.save()
newposts.save_m2m()
return HttpResponseRedirect('/tweaks/tweaks')
else:
print("errors",form.errors) # Print the errors on console
return HttpResponseRedirect('/tweaks/tweaks')
Related
I found posts with similar problem, but the solutions dont seem to work with me. Or maybe I am missing something.
I created a form in Django, but as a default it seems that every mandatory fields have this "this field is required" text above.
Ideally, I would like to have this only when someone tries to submit a form and a field is missing.
form.py
class ElderFlowerChampFormAdmin(ModelForm):
fieldsets=[
("Look",{'fields':[
('look_colour','look_clarity','look_effervescence')]}),
}
widgets = {
'user': forms.Select(attrs={'class':'form-control','required':'True'}),
'look_colour':forms.Select(attrs={'class':'form-control','required':'True'}),
}
view.py
def elderflowerchamp(request, product_id):
global ChampageRating
product = Product.objects.get(pk=product_id)
url = request.META.get('HTTP_REFERER')
submitted = False
try:
if request.method == "POST":
reviews = ChampageRating.objects.get(pk=product_id)
if request.user.is_superuser:
form = ElderFlowerChampFormAdmin(request.POST, instance=reviews)
if form.is_valid():
form.save()
return redirect('home')
else:
form = ElderFlowerChampForm(request.POST, instance=reviews)
if form.is_valid():
ChampageRating = form.save(commit=False)
ChampageRating.user = request.user
ChampageRating.save()
return redirect('home')
else:
#This part goes to the page, but doesnt submit
reviews = ChampageRating.objects.get(pk=product_id)
if request.user.is_superuser:
form = ElderFlowerChampFormAdmin
else:
form = ElderFlowerChampForm
if 'submitted' in request.GET:
submitted = True
except:
reviews = None
if request.user.is_superuser:
form = ElderFlowerChampFormAdmin(request.POST)
if form.is_valid():
data = ChampageRating()
data.rating = form.cleaned_data['rating']
data.look_colour = form.cleaned_data['look_colour']
data.ip = request.META.get('REMOTE_ADDR')
data.product_id = product_id
data.user_id = request.user.id
data.save()
messages.success(request, 'Thank you! Your review has been submitted.')
return redirect('home')
else:
form = ElderFlowerChampForm(request.POST)
if form.is_valid():
data = ChampageRating()
data.rating = form.cleaned_data['rating']
data.look_colour = form.cleaned_data['look_colour']
data.ip = request.META.get('REMOTE_ADDR')
data.product_id = product_id
data.user_id = request.user.id
data.save()
messages.success(request, 'Thank you! Your review has been submitted.')
return redirect('home')
return render(request,"main/ElderFlowerReview.html", {'form':form, 'submitted':submitted,'reviews':reviews, 'product':product})
models.py
LOOKCOLOUR=(
(1,'Straw'),
(2,'Yellow'),
(3,'Gold'),
(4,'Amber'),
)
class ChampageRating(models.Model):
user = models.ForeignKey(User,blank=True, on_delete=models.CASCADE)
product=models.ForeignKey(Product,related_name="champcomments", on_delete=models.CASCADE)
look_colour=models.IntegerField(choices=LOOKCOLOUR, default=0)
def __str__(self):
return '%s - %s - %s'%(self.user, self.product, self.date_added)
Any ideas
something wrong on case request.GET here:
if request.user.is_superuser:
form = ElderFlowerChampFormAdmin
else:
form = ElderFlowerChampForm
You send the FormClass into the template context, and not the form instance.
Also see eror on the except case: If i have a GET, i should not render BoundedForm, here should be form.bounded = false (form is not bounded with any data). But you are always made the BoundedForm, with the request.POST data after error here:
reviews = ChampageRating.objects.get(pk=product_id)
My opinion is - you should try to read about Django-GCBV, it is better way to avoid complex errors, like in your question.
https://docs.djangoproject.com/en/4.0/topics/class-based-views/
I'm new in django,I just have the error, AttributeError at /registro/ 'NoneType' object has no attribute 'groups', but my form is saving all the data
views.py
def register(request):
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
ui = User()
ui.username = request.POST.get('username')
ui.password = request.POST.get('password')
ui.first_name = request.POST.get('first_name')
ui.last_name = request.POST.get('last_name')
ui.email = request.POST.get('email')
# user = User.objects.create_user(username=username,first_name=first_name,last_name=last_name,email=email,password=password)
user = ui.save()
obj = User.objects.latest('id')
cli = Client_profile_master()
cli.first_name = request.POST.get('first_name')
cli.last_name = request.POST.get('last_name')
cli.email = request.POST.get('email')
cli.mobile_no = request.POST.get('mobile')
cli.address_1 = request.POST.get('address1')
cli.address_2 = request.POST.get('address2')
cli.image=request.FILES.get('image')
cli.user=obj
# emp.save()
# client = Client_profile_master.objects.create(first_name=first_name,last_name=last_name,email=email,mobile=mobile,address1=address1,address2=address2,image=image,user=obj)
cli.save()
username = form.cleaned_data.get('username')
group = Group.objects.get(name='Client')
user.groups.add(group)
messages.success(
request, f'Account created successfully for {username} !!!')
return redirect('login')
else:
return redirect('/')
else:
form = CreateUserForm()
return render(request, 'sites/register.html', {'form': form})
The error is occuring for this line: user = ui.save(), Model's save method does not return anything(or returns None), hence value of user is None. Easy fix would be to use ui.groups.add(group).
But you can improve your implementation a lot by using the forms, which you are already using as well as by adding a new one. For example:
# form
class CliForm(forms.ModelForm):
class Meta:
model = ClientProfileMaster # Using camelcase when declairing class name
exclude = ["user",]
# view
form = CreateUserForm(request.POST)
cli_form = CliForm(request.POST, request.FILES)
if form.is_valid() and cli_form.is_valid():
user = form.save()
cli = cli_form.save(commit=False)
cli.user = user
cli.save()
For more information, please the django modelform's documentation.
Please Help!
I am trying to update a group of formsets that are related the main form (Project Information) by the main forms pk. The create form works fine, but I am finding it extremely difficult to implement the update version.
It's the save as an update part that I can't figure out for the formsets. The main form updates the database correctly. The formsets just create new records instead of updating the existing ones. I do not know how to instance the formsets.
Here the code.
view.py
#login_required
def edit_project(request):
SampleInformationFormSet = formset_factory(SampleInformationForm, extra=1)
DissolutionMethodsFormSet = formset_factory(DissolutionMethodsForm, extra=1)
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
d_formset = DissolutionMethodsFormSet(request.POST or None, prefix='d')
if request.method == 'POST':
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
d_formset = DissolutionMethodsFormSet(request.POST or None, prefix='d')
pi_pk = ''
p = ''
if form.is_valid():
pi_pk = form.cleaned_data['hd']
p = ProjectInformation.objects.get(pk=pi_pk)
form = ProjectInformationForm(request.POST, instance=p)
form.save() # This form saves correctly
for si_form in si_formset:
si_form.save() # I do not know how to attach an instance to these formsets
for d_form in d_formset:
d_form.save()
messages.success(request, 'Your project has been updated!')
return redirect('edit_project')
else:
pass
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
messages.warning(request, 'There was an error saving your form.')
study_id_select = list(
ProjectInformation.objects.values('dissolution_study_id', 'id').filter())
context = {'form': form, 'si_formset': si_formset, 'd_formset': d_formset, 'study_id_select': study_id_select}
return render(request, 'main/edit_project.html', context)
models.py I'm just going to include part of three of the seven models to keep this a little shorter.
class ProjectInformation(models.Model):
username = models.ForeignKey(User, on_delete=models.CASCADE)
compound_code = models.CharField(max_length=60)
product_type = models.ForeignKey(ProductType, on_delete=models.CASCADE)
main_component = models.CharField(max_length=100)
class SampleInformation(models.Model):
sample_index = models.CharField(max_length=30)
sample_type_purpose = models.ForeignKey(SampleTypePurpose, on_delete=models.CASCADE)
specification_number = models.CharField(max_length=20, blank=True, null=True)
project = models.ForeignKey(ProjectInformation, on_delete=models.CASCADE, blank=True, null=True)
class DissolutionMethods(models.Model):
number_of_methods = models.IntegerField(default=1,
validators=[MaxValueValidator(10), MinValueValidator(1)],
blank=True, null=True)
dissolution_method_index = models.CharField(max_length=10)
project = models.ForeignKey(ProjectInformation, on_delete=models.CASCADE, blank=True, null=True)
forms.py
class ProjectInformationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['hd'] = forms.CharField(widget=forms.HiddenInput, required=False)
class Meta:
model = ProjectInformation
fields = '__all__'
class SampleInformationForm(forms.ModelForm):
class Meta:
model = SampleInformation
fields = '__all__'
Please help if you can. This project has been a trial by fire and the flames are hot!
Finally solved it myself.
#login_required
def edit_project(request):
SampleInformationFormSet = formset_factory(SampleInformationForm, extra=1)
DissolutionMethodsFormSet = formset_factory(DissolutionMethodsForm, extra=1)
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
d_formset = DissolutionMethodsFormSet(request.POST or None, prefix='d')
if request.method == 'POST':
form = ProjectInformationForm(request.POST or None)
si_formset = SampleInformationFormSet(request.POST or None, prefix='si')
d_formset = DissolutionMethodsFormSet(request.POST or None, prefix='d')
pi_pk = ''
p = ''
if form.is_valid():
pi_pk = form.cleaned_data['hd']
p = ProjectInformation.objects.get(pk=pi_pk)
form = ProjectInformationForm(request.POST, instance=p)
form.save()
si = p.sampleinformation_set.all() # All the Methods related to the instance
d = p.dissolutionmethods_set.all()
si_cnt = 0
for si_form in si_formset:
if si_form.is_valid():
update = si_form.save(commit=False)
update.pk = si[si_cnt].pk
update.save()
si_cnt += 1
d_cnt = 0
for d_form in d_formset:
if d_form.is_valid():
update = d_form.save(commit=False)
update.pk = d[d_cnt].pk
update.save()
d_cnt += 1
I'm using Django Model Form. Can anyone help me validate those fields to get field error using clean()?
The Name field cannot be repeated in the same office, only in a different one.
form.py
class CreateSalesRepForm(forms.ModelForm):
class Meta:
model = CreateSalesRep
fields = ['name', 'office']
widgets = {
'office': forms.Select(attrs={'class': 'form-control', 'placeholder': 'Enter Office'}),
'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter Name'})
}
UPDATED (form.py) --- Here is the solution, you can use this codes to validate both insert and update form.
def clean(self):
cleaned_data = super().clean()
office = cleaned_data.get("office")
name = cleaned_data.get("name")
duplicates = CreateSalesRep.objects.filter(office=office, name=name)
if (self.instance.pk and None):
duplicates = duplicates.filter(pk=self.instance.pk)
if duplicates.exists():
msg = "Name already exist in office selected"
self.add_error('name', msg)
self.add_error('office', msg)
view.py
def create_salesrep(request):
if request.method == "POST":
form = CreateSalesRepForm(request.POST or None)
if form.is_valid():
form.save()
messages.success(request, 'Successfully Saved!', 'alert-success')
return redirect('sales_rep')
else:
return render(request, 'salesrep/create_salesrep.html', {'form':form})
else:
form = CreateSalesRepForm()
context = {'form':form}
return render(request, 'salesrep/create_salesrep.html', context)
def update_salesrep(request, pk):
srep = CreateSalesRep.objects.get(id=pk)
form = CreateSalesRepForm(instance=srep)
if request.method == "POST":
form = CreateSalesRepForm(request.POST or None, instance=srep)
if form.is_valid():
form.save()
messages.success(request, 'Successfully Updated!', 'alert-success')
return redirect('sales_rep')
else:
return render(request, 'salesrep/update_salesrep.html', {'form':form})
else:
form = CreateSalesRepForm(instance=srep)
return render(request, 'salesrep/update_salesrep.html', {'form':form})
You can validate in the forms:
class CreateSalesRepForm(forms.ModelForm):
class Meta:
model = CreateSalesRep
fields = ['name', 'office']
def clean(self):
cleaned_data = super().clean()
office= cleaned_data.get("office")
name = cleaned_data.get("name")
duplicates = CreateSalesRep.objects.filter(office=office, name=name)
if self.instance.pk:
duplicates = duplicates.filter(pk=self.instance.pk)
if duplicates.exists():
raise forms.ValidationError('Name already in office')
That being said, you could enforce this in the model/db level as well by adding the following to your CreateSalesRep model:
class CreateSalesRep(models.Model):
...
class Meta:
unique_together = ['office', 'name']
You can try following inside your model class
class Meta:
unique_together = [('office', 'name')]
I have a new problem, it is when I insert in the database the news, it adds but without the region. How can I insert the comment with the correct region?
Here is my view :
def index_region(request,region):
try:
actuCommentaire = Actu.objects.get(region=region)
except ObjectDoesNotExist:
actuTempo = Actu(region=region)
actuCommentaire = actuTempo.commentaire
form = UpdateActu(request.POST or None, instance=actuCommentaire)
if form.is_valid():
form.save()
return redirect('index.html')
Here is my model "Actu" :
class Actu(models.Model):
commentaire = models.TextField(max_length=200, null=True)
region = models.CharField(max_length=30, null=True)
def __str__(self):
return self.region
Here is my form :
class UpdateActu(forms.ModelForm):
class Meta:
model = models.Actu
fields = ['commentaire']
widgets = {
'commentaire': forms.Textarea(attrs={'class': 'form-control', 'id': 'exampleTextarea', 'rows': '2'})
}
Here is the result when inserting into the database :
enter image description here
I found how to solve the problem.
Here is my new view :
try:
actuCommentaire = Actu.objects.get(region=region)
except ObjectDoesNotExist:
actuTempo = Actu(region=region)
actuCommentaire = actuTempo.commentaire
form = UpdateActu(request.POST or None, instance=actuCommentaire)
if form.is_valid():
if Actu.objects.filter(region=region).count() == 0:
formActu = Actu(commentaire=request.POST['commentaire'], region=region)
formActu.save()
else:
form.save()
return redirect('index.html')