How to POST data to a Django Form that contains checkboxes - django

I have a problem when I am testing my registration form in Django. I am trying to make a POST request but I cannot select a checkbox field.
self.response = self.client.post(url, {
'username': 'testuser',
'password': 'testuserpassword',
'first_name': 'testtt',
'last_name': 'userrr',
'image': '',
'email': 'testuser#gmail.com',
'gender': 'M',
'dob': '10/10/1996',
'hobby': 'Fishing'
})
This is my line of code. The problem is at Hobby. The registration page is made of two forms. A profile form and a hobby form. There is a many-to-many relationship between Profile and Hobby models.
When I make the above POST request, I get this (Select a valid choice):
Thank you in advance!

According to the screenshot you've posted, the value for each hobby checkbox corresponds to an integer - 1, 2, 3, 4, etc. That would imply that the backend is expecting the hobby ID to be transmitted in the form. However, the test is not sending the hobby ID, it's sending the name.
Change the name to the corresponding ID - e.g.
self.response = self.client.post(url, {
...
'hobby': 1 # Fishing
})

Related

Creating a Apache superset user through API

I want to create user through apache superset API if user already exist it should show message.
import requests
payload = { 'username': 'My user name',
'password': 'my Password',
'provider': 'db'
}
base_url="http://0.0.0.0:8088"
login_url =f"{base_url}/api/v1/security/login"
login_response =requests.post(login_url,json=payload)
access_token = login_response.json()
print(access_token)
# header
header = {"Authorization":f"Bearer {access_token.get('access_token')}"}
base_url="http://0.0.0.0:8088" # apache superset is running in my local system on port 8088
user_payload={
'first_name': "Cp",
'last_name': "user",
'username':"A",
'email': "user.#gmail.com",
'active': True,
'conf_password': "user#1",
'password': "user#1",
"roles":["Dashboard View"]
}
users_url = f"{base_url}/users/add"
user_response= requests.get(users_url, headers=header)
print(user_response)
print(user_response.text)
user_response = user_response.json()
print(user_response)
I tried to create user through mentioned API, some time it gives 200 success message, but after checking in apache superset website i can not see created user details.
If i am using the wrong API endpoint or wrong methods to create user please suggest me.

Deal with multiple forms from the same Model in Django

I have a template page where I can create multiple jobs at the same time.
They all use the same Form, and when I submit the form, I receive POST data on the view like this:
<QueryDict: {'csrfmiddlewaretoken': ['(token)'], 'name': ['name1', 'name2', 'name3'], 'min': ['1', '2', '3'], 'max': ['10', '20', '30'], 'color': ['green', 'blue', 'red']}>
In the view, when I do
form = JobForm(request.POST), I get the following clean data {'name': 'name3', 'min': 3, 'max': 30, 'color': 'red'}. I have seen this solution, but I don't know how many Jobs will be created at the same time so I can't create different prefixes on the view, so I only send the form to the template like this form = JobForm().
How can I check if all the submitted data is valid and create all the objects in a single page submission?

Why does my Django form not raise Validation Error?

I read through most SO cases regarding this issue but all are kind of specific, so I come here for help.
I have impelemented a range filter in my Django project that takes in two inputs set to a low bound and high bound value, and displays the range of data within those bounds.
What I'm trying to do, is make it so when a user inputs a higher number in the low bound than the high bound value, a ValidationError is raised for the user to see on the front end, and results are not displayed. I am a bit new to working with Django forms, but I can supply my code, and maybe someone could provide a solution
forms.py
class PlayerForm(forms.Form):
# player forms
points_high = forms.IntegerField(validators = [MinValueValidator(0)],
min_value=0,
label = 'Reviews',
required = False,
widget = forms.NumberInput(
attrs={'id': 'pointsHigh',
'name': 'pointsHigh',
'href': '#',
'value': '',
'class': "form-control"}))
points_low = forms.IntegerField(validators = [MinValueValidator(0)],
min_value=0,
required = False,
widget = forms.NumberInput(
attrs={'id': 'pointsLow',
'name': 'pointsLow',
'href': '#',
'value': '',
'class': "form-control"}))
def check_bounds(self):
"""custom validation to check if low bound value is higher than high bound value"""
data = self.cleaned_data
player_low = data['player_low']
player_high = data['player_high']
if player_low and player_high:
if player_low > player_high:
raise forms.ValidationError(_("Low bound value cannot be higher than high bound value!"))
return data
views.py
def player_points(request):
players_form = PlayerForm()
players_high = request.GET.get('players_high')
players_low = request.GET.get('players_low')
stat_kwargs = {points__lte: players_high,
points__gte: players_low}
players = Players.objects.filter(**stat_kwargs)
context = {
'players': players
'form': players_form
}
return render(request, 'nba/players.html', context)
Essentially, the goal is to take user input, check it in our check_bounds function, and return the Error if it doesn't work. How can I do that?
The form will not call your function automatically. You will need to add in to your form a place to call your function. One place you could do this is you can override the form clean() function. Something like this:
def clean(self):
cleaned_data = super().clean()
self.check_bounds()
This will call your function when your django form would normally call the clean() function.
Also, I don't really understand the purpose of the line return data in your check_bounds() function. What is the reason you put that line in there?

django test for upload image

i want to test user registration but i can't test image here is my test:
test.py
response = self.client.post('/api/v1/signup/',
content_type='application/json',
data=json.dumps({"username": "casino", "email": "casinoluxwin#gmail.com",
"password1": "android12", "password2": "android12", "photo": {
'real_filename': "u'banner3.jpg'",
'path': "u'C:/Users/Dima/Desktop'"}
}))
self.assertEqual(response.status_code, 200)
i get code 400(bad request), but without photo my test pass
service/users.py
#validate_input({
'username': {'min_length': 3, 'max_length': 50},
'email': {'validation_type': "email", 'max_length': 50},
'password1': {'min_length': 8, 'max_length': 50},
'password2': {'min_length': 8, 'equal_to': 'password1',
'messages': {'equal_to': _(u"Пароли не совпадают")}},
'photo': {'required': True}
})
#transaction.atomic
def signup(self, data):
user_data = {
'username': data['username'],
'email': data['email'],
'password': data['password1'],
'coins_amount': 0
}
user = self._create_user(user_data)
if data.get("photo"):
self._attach_photo(user, data["photo"])
obj, created = VerificationCode.objects.get_or_create(user=user, code_type="registration")
obj.create_expiration_date()
obj.create_code()
obj.save()
return user.id
So i want to test user photo anything else works fine. Thanks for any help
Problem probably resides in either Users._attach_photo() or your user model. Not enough information here to decipher it entirely. There are a couple of things to try.
I'd write a normal unittest that does not use the client. It'll give you a more helpful traceback than just the HTTP status code from the running server. Something like:
def test_user_add_method(self):
x = Users.signup(json.dumps({"username": "casino", "email": "casinoluxwin#gmail.com",
"password1": "android12", "password2": "android12", "photo": {
'real_filename': "u'banner3.jpg'",
'path': "u'C:/Users/Dima/Desktop'"})
Users.get(pk=x) #will fail if user was not created.
Second, try commenting out your validator. 400 bad request could easily be kicked off by that. It is possible that your validator isn't playing nice with the image and you'll have to mess around with that.

Django unit testing; POST checkboxes with multiple values

I am trying to run a unit test on a form with multiple checkboxes, but cannot figure out how to send the POST data. The most similar question I can find is here. But how do I embed that url-encoded piece into the POST with the other form data?
If I do something like this, my test errors out and says classes = request.POST.getlist('class_choices')
AttributeError: 'dict' object has no attribute 'getlist':
request = HttpRequest()
request.method = 'POST'
request.POST['fname'] = 'A'
request.POST['lname'] = 'Student'
request.POST['email'] = 'me#name.com'
request.POST['class_choices'] = urllib.urlencode({
'class_choices': ['1', '2'],
}, True)
request.POST['passwd'] = 'password'
request.POST['conpasswd'] = 'password'
response = success(request)
self.assertIn('My Browser', response.content.decode())
But if I do this, I get an error on fname = request.POST['fname']
TypeError: string indices must be integers, not str
request.POST = urllib.urlencode({
'class_choices': ['1', '2'],
'fname': 'A',
'lname': 'Student',
'email': 'me#name.com',
'passwd': 'password',
'conpasswd': 'password'
}, True)
response = success(request)
So after trying out a couple other things, I'm basically going to say there is "technically" no answer to my question...I could not find any way to create a checkbox-type POST argument using HttpRequest. However, doing it the 'right' way with the Django test client as Hieu Nguyen suggested does allow for that capability. You just have to encapsulate the multiple options in parantheses, as:
response = c.post('/success/',{
'fname': 'A',
'lname': 'Student',
'email': 'me#name.com',
'passwd': 'password',
'conpasswd': 'password',
'class_choices': ('1','2'),
})