How to remove "this field is not required" in django? - python

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/

Related

Django - Unable to find object using pk (Matching query DoesNotExist)

Whenever I try to create a "Tour" for a "User" I get this error:
"DoesNotExist at /add-tour/FAjK5CryF8/ - User matching query does not exist."
Specifically the problems seems to come from this line of code:
user = User.objects.get(pk=pk)
models.py
class Tour(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
tour_date = models.DateField(default=date.today)
tour_fans = models.ForeignKey(FanAccount, on_delete=models.PROTECT)
def __str__(self):
return f"{self.user} del {self.tour_date}"
views.py
def tour_new(request, pk):
user = User.objects.get(pk=pk)
if request.method == "POST":
form = TourForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.tour_fans = request.user
form.instance.user = user
instance.save()
form.save()
return render(request, "tour.html", {"form": TourForm(), "success": True})
else:
form = TourForm()
return render(request, "tour.html", {"form": form})
For "User" I'm using a custom Primary Key (ShortUUID).
I'm new to Python and Django so it may be something easily solvable, but after hours of attempts I seem unable to solve it.
You need to make sure your user instance does exist, so you should instead of user = User.objects.get(pk=pk)call user = get_object_or_404(User, pk=pk), then you need to pass user as an instance:
if request.method == "POST":
form = TourForm(request.POST, instance=user)

Django model form, adding a user id when creating new note

I'm pretty new to Django, I've been stuck on this view for a little while. My goal with this form is to be able to create a small note on a "Property" about maintenance or other information. The note would log the time, date, note and the user that recorded the note. Any help would be appreciated.
View:
#login_required(login_url="login")
def createNote(request, pk):
PropertyNoteFormSet = inlineformset_factory(
Property, PropertyNote, fields=('note', 'user',))
property_note = Property.objects.get(id=pk)
form = PropertyNoteFormSet(instance=property_note)
# form = OrderForm(initial={'customer': customer})
if request.method == "POST":
print(request.POST)
form = PropertyNoteFormSet(
request.POST, instance=property_note)
if form.is_valid():
form.save()
return redirect("/")
context = {"form": form}
return render(request, "dashboard/create_note.html", context)
Here is the ModelForm:
class PropertyNoteForm(ModelForm):
class Meta:
model = PropertyNote
fields = ['note']
exclude = ['user']
Here is the Model:
class PropertyNote(models.Model):
airbnb_name = models.ForeignKey(Property, blank=True,
null=True,on_delete=models.CASCADE)
note = models.TextField(blank=True, null=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.note
The form comes out with around 4 boxes to fill in. Currently it works, but you have to actually select the user that is posting the note, I would like this part to be handled automatically and use the current logged in user. I think I still have a whole lot of holes in my knowledge around this stuff, I just can't seem to work it out.
Thanks in advance.
Edit:
I've tried this:
def createNote(request, pk):
PropertyNoteFormSet = inlineformset_factory(
Property, PropertyNote, fields=('note',), extra=1)
property_note = Property.objects.get(id=pk)
form = PropertyNoteFormSet(
queryset=PropertyNote.objects.none(), instance=property_note)
# form = OrderForm(initial={'customer': customer})
if request.method == "POST":
print(request.POST)
form = PropertyNoteFormSet(
request.POST, instance=property_note)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
print(instance.user)
instance.save()
return redirect("/")
context = {
"form": form,
'pk': pk,
}
return render(request, "dashboard/create_note.html", context)
But I get this:
AttributeError at /create_note/75/
'list' object has no attribute 'user'
Request Method: POST
Request URL: http://127.0.0.1:8000/create_note/75/
Django Version: 3.0.4
Exception Type: AttributeError
Exception Value:
'list' object has no attribute 'user'
you can use request.user.id to get the logged user id in your view.
See Documentation in Django
#login_required(login_url="login")
def createNote(request, pk, **kwargs):
note_form = PropertyNoteForm()
if request.method == "POST":
note_form = PropertyNoteForm(request.POST)
if note_form.is_valid():
add_note = note_form.save(commit=False)
add_note.user = request.user
add_note.airbnb_name =
Property.objects.get(id=pk)
add_note.save()
return redirect('/property/' + pk + '/')
context = {
"form": note_form,
'pk': pk,
}
return render(request, "dashboard/create_note.html", context)
I solved it with the above code. Using instance was the incorrect thing to do here. I didn't need to create an instance and I didn't need the inline form. I simply needed a new form:
note_form = PropertyNoteForm()
The user input information, I need to send that information to check if it's valid:
if request.method == "POST":
note_form = PropertyNoteForm(request.POST)
if note_form.is_valid():
Then I needed to populate the form with information that was not already in the form from the user:
add_note = note_form.save(commit=False)
add_note.user = request.user
add_note.airbnb_name = Property.objects.get(id=pk)
add_note.save()
return redirect('/property/' + pk + '/')

Remove user in Django

I would like to remove user.
I know that probably I can use some library like allauth but I want to do this on my view.
I didn't find any tutorial for that so I am trying to do this learn-by-mistakes way.
Ok. so in urls I have:
urlpatterns = [
('^remove$', views.remove_user, name="remove"),
]
forms:
class RemoveUser(forms.ModelForm):
class Meta:
model = User
fields = ('username',)
views:
#login_required(login_url='http://127.0.0.1:8000/')
def remove_user(request):
if request.method == 'POST':
form = RemoveUser(request.POST)
username = request.POST.get('username')
if form.is_valid():
rem = User.objects.get(username=username)
rem.delete()
return redirect('main')
else:
form = RemoveUser()
context = {'form': form}
return render(request, 'remove_user.html', context)
I can access website and type text in textfield. When I type random username I get error "user does not exist" so everything ok, but when I type correct username I get message: "A user with that username already exists" and this user is not removed.
Please, can you help me with that?
Change your form to a normal form-
class RemoveUser(forms.Form):
username = forms.CharField()
The view will be as follows -
#login_required(login_url='http://127.0.0.1:8000/')
def remove_user(request):
if request.method == 'POST':
form = RemoveUser(request.POST)
if form.is_valid():
rem = User.objects.get(username=form.cleaned_data['username'])
if rem is not None:
rem.delete()
return redirect('main')
else:
## Send some error messgae
else:
form = RemoveUser()
context = {'form': form}
return render(request, 'remove_user.html', context)
EDIT-- Another way to approach the same problem is to deactivate the user
if form.is_valid():
rem = User.objects.get(username=form.cleaned_data['username'])
if rem is not None:
rem.is_active = False
rem.save()

Django UserProfile Forms

I have a Django form that allows a user to save their UserProfile details, but it only allows this to occur once. Given that additional saves ask to create a new entry, but i have a one-to-one relation between the user field and user UserProfile field.
When a user is created a UserProfile entry is not created. Rather they cannot access their account until these details are filled out.
I want to pre-populate the form with existing data when a student goes to access the form a second time.
def student_details(request):
#this is a form
if request.user.is_authenticated():
if request.method == 'POST':
form = DetailsForm(request.user, request.POST, request.FILES)
if form.is_valid():
note = form.save(commit=False)
note.user = request.user
note.completed_form = True
note.save()
return HttpResponseRedirect('/student-portal/')
else:
if request.user.get_profile():
pass
form = DetailsForm(request.user)
else:
form = DetailsForm(request.user)
return render_to_response("student-details.html", {'form': form}, context_instance=RequestContext(request))
return HttpResponseRedirect('/')
Sorry guys just found out how to do this:
def student_details(request):
#this is a form
if request.user.is_authenticated():
if request.method == 'POST':
form = DetailsForm(request.user, request.POST, request.FILES)
if form.is_valid():
note = form.save(commit=False)
user_profile = UserProfile.objects.get(user=request.user)
if user_profile:
note.id = user_profile.id
note.user = request.user
note.completed_form = True
note.save()
return HttpResponseRedirect('/student-portal/')
else:
try:
user_profile = UserProfile.objects.get(user=request.user)
form = DetailsForm(request.user, instance=user_profile)
except:
form = DetailsForm(request.user)
return render_to_response("student-details.html", {'form': form}, context_instance=RequestContext(request))
return HttpResponseRedirect('/')
The idea here is to query to see if a user_profile linked to that user already exists and then specify the ID for that entry.

Django - handling a large number of forms

I'm starting to work on a website, which obviously will have a ton of buttons, and I still only have 2 buttons to handle, and one of my views already has this piece of code to handle just those two form submissions
if request.method == "POST":
if "see" in request.POST:
seetagform = SeeTagForm(request.POST)
createform = CreateForm()
if seetagform.is_valid():
cd = seetagform.cleaned_data
tagstring = "_".join(cd["name"].split(' '))
return HttpResponseRedirect(reverse("base:see",args=(tagstring,)))
elif "create" in request.POST:
createform = CreateForm(request.POST)
seetagform = SeeTagForm()
if createform.is_valid():
cd = createform.cleaned_data
p = Event.objects.create(start=cd["datetime"])
tags = cd["tags"]
tags = tags.split(' ')
for tag in tags:
t = Tag.objects.get(name=tag)
t.events.add(p)
return HttpResponseRedirect(reverse("base:see",args=(tagstring,)))
else:
createform = CreateForm()
seetagform = SeeTagForm()
else:
createform = CreateForm()
seetagform = SeeTagForm()
Well, as far as I can sense, these are many if's and else's for only 2 buttons (but everything here is needed), so I wonder the confusion it might be when I have like 12 buttons across my page. This doesn't look too pythonic!
Is there a simpler/more clever way to handle many form submissions?
Thanks in advance
I am doing it also that way, just adding prefix to the buttons name to be more clear
#login_required
def profile_view(request):
message = None
user = MyUser.objects.get(pk=request.user.pk)
addresses = user.profile_address.all()
AddressFormSet = modelformset_factory(Address, fields=['city','zip_code','address','phone','default_address',
'first_name','last_name'])
address_formset = AddressFormSet(queryset=addresses)
profile_form = ProfileForm(instance=user)
pass_form = PasswordChangeForm()
if request.method == "POST":
if 'btn_profile' in request.POST:
profile_form = ProfileForm(request.POST, instance=user)
if profile_form.is_valid():
profile_form.save()
messages.add_message(request, messages.INFO, 'Successfully changed your profile')
return HttpResponseRedirect(reverse('profile'))
if 'btn_pass' in request.POST:
pass_form = PasswordChangeForm(request.POST)
if pass_form.is_valid():
user.set_password(pass_form.cleaned_data['password1'])
user.save()
messages.add_message(request, messages.INFO, 'Successfully changed your password')
return HttpResponseRedirect(reverse('profile'))
if 'btn_address' in request.POST:
address_formset = AddressFormSet(request.POST)
if address_formset.is_valid():
for address_form in address_formset:
if address_form.is_valid() and address_form.has_changed():
address = address_form.save(commit=False)
address.user_profile = user
address.save()
return HttpResponseRedirect(reverse('profile'))
orders = Order.objects.filter(user = user).order_by('-created')
context = {
'address_formset': address_formset,
'pass_form': pass_form,
'profile_form':profile_form,
'message':message,
'orders':orders,
}
return render(request,'custom_auth/profile.html', context)

Categories