'QuerySet' object is not callable - django

I have this function that must get the class code, and then look for this class in the database, then fill in the participant field of this class with the user who is authenticated.
`def participar(request):
cc = nameUser(request)
if request.method == 'POST':
busca = request.POST.get('busca')
turma = Turma.objects.filter(codigo=busca)
obj = turma(participantes=request.user)
obj.save()
else:
return render(request, 'turmas/participar.html', cc)
return render(request, 'turmas/participar.html', cc)`
but when trying to add the following error occurs on the line turma(participantes=request.user)
'QuerySet' object is not callable
what was expected is that after searching for the desired class by its code, the authenticated user would be added to the participant field of that class

Related

get_or_create not creating my object with attributes that I need

So I am attempting to get_or_create a conversation object. Now, if the object is already created, the code works fine. But if it's not created, it will create the conversation object, BUT not with the members that I am trying to pass. An empty conversation object. members is a manytomany field to User. What am I doing wrong here?
views/message
def message (request, profile_id):
if request.method == 'POST':
form = MessageForm(request.POST)
if form.is_valid():
form.save()
return redirect('dating_app:messages', profile_id)
else:
conversation, created = Conversation.objects.filter(members = request.user).filter(members= profile_id).get_or_create()
other_user = conversation.members.filter(id=profile_id).get()
form = MessageForm({'sender': request.user, 'conversation': conversation})
context = {'form' : form, 'other_user': other_user }
return render(request, 'dating_app/message.html', context)
models.py/Conversation
class Conversation(models.Model):
members = models.ManyToManyField(settings.AUTH_USER_MODEL)
So, I figured out by using 'add()' to add my members after I created my object since it's a many to many field.
conversation, created = Conversation.objects.filter(members = request.user).filter(members= profile_id).get_or_create()
conversation.members.add(request.user, profile_id)

Is there a way to access request object in django inline formset clean method?

Got this admin class with inline and form classes:
class InvoiceAdmin(admin.ModelAdmin):
....
inlines = [InvoiceLineInline, ]
form = InvoiceForm
....
class InvoiceForm(forms.ModelForm):
....
def clean():
....
class Meta:
model = Invoice
exclude = []
class InvoiceLineInline(admin.TabularInline):
model = InvoiceLine
formset = InvoiceLineInlineFormset
extra = 1
class InvoiceLineInlineFormset(forms.models.BaseInlineFormSet):
def clean(self):
super(InvoiceLineInlineFormset, self).clean()
count = 0
for form in self.forms:
if not hasattr(form, 'cleaned_data'):
continue
data = form.cleaned_data
try:
if data:
count += 1
else:
continue
except AttributeError:
pass
if Decimal(data.get('quantity', 0)) <= 0:
raise forms.ValidationError("Amount should be greater than 0.")
******************************************************
_stock_code = data.get('stock_code', None)
if not len(fetch_stocks_from_connector(request, stock_code=_stock_code)):
raise forms.ValidationError("{} Stock code does not exist at connector.".format(_stock_code))
******************************************************
if count < 1:
raise forms.ValidationError('Need one line at least.')
I need to do extra validation with an external method for the _stock_code value in each inlineform within InvoiceLineInlineFormset.clean as displayed above between the starred lines. But external method needs request object as argument to run properly.
Is it possible to pass request object to clean method?
The question is old but I'll share the solution that worked for me
ModelAdmin has a get_formset method. You can extend it like this
class YourAdminInline(admin.TabularInline):
model = YourModel
formset = YourInlineFormSet
def get_formset(self,request,obj=None,**kwargs):
formset = super(YourAdminInline,self).get_formset(request,obj,**kwargs)
formset.request = request
return formset
In your formset you can access the request object using self.request. For example in the clean method
class YourInlineFormset(forms.BaseInlineFormset):
def clean(self):
...
request = self.request
Base ModelAdmin class has _create_formsets() method which, well, generates formsets:
def _create_formsets(self, request, obj, change):
"Helper function to generate formsets for add/change_view."
formsets = []
inline_instances = []
prefixes = {}
get_formsets_args = [request]
if change:
get_formsets_args.append(obj)
for FormSet, inline in self.get_formsets_with_inlines(*get_formsets_args):
prefix = FormSet.get_default_prefix()
prefixes[prefix] = prefixes.get(prefix, 0) + 1
if prefixes[prefix] != 1 or not prefix:
prefix = "%s-%s" % (prefix, prefixes[prefix])
formset_params = {
'instance': obj,
'prefix': prefix,
'queryset': inline.get_queryset(request),
}
if request.method == 'POST':
formset_params.update({
'data': request.POST,
'files': request.FILES,
'save_as_new': '_saveasnew' in request.POST
})
formsets.append(FormSet(**formset_params))
inline_instances.append(inline)
return formsets, inline_instances
As you can see by extending formset_params with method's request argument in your ModelAdmin class you can then save extra kwarg with request in formset's class __init__() and later use it in clean() method via self.request.
Note that this is not the cleanest solution as method implementation does not allow to extend only kwargs easily so entire method needs to be moved to your ModelAdmin and with any Django's update of this part of code you will need to update your method accordingly.
I had pretty much the same question (how to get request.user stuff from inline methods) and I got this answer which worked for me:
Django: access to user info from admin.py for methods with no request object?

Django 1.11: "global name 'user' is not defined"

I have a survey app - you create a Survey and it saves the Response. It's registered in Django Admin. I can see the Survey and submit a Response. When I click Response in Admin, I get the following error:
ValueError at /admin/django_survey/response/
Cannot query "response 5f895af5999c49929a522316a5108aa0": Must be "User" instance.
So I checked the SQL database and for django_survey_response I can see that there is a response, but the column user_id is NULL.
I suspected that there's an issue with my Views and/or Forms and I'm not saving the logged in User's details, so I've tried to address that.
However, now I get
NameError at /survey/1/
global name 'user' is not defined
How do I resolve this? I want the form to save Response with the logged in user's ID.
The Traceback:
django_survey\views.py
def SurveyDetail(request, id):
survey = Survey.objects.get(id=id)
category_items = Category.objects.filter(survey=survey)
categories = [c.name for c in category_items]
print 'categories for this survey:'
print categories
if request.method == 'POST':
form = ResponseForm(request.POST, survey=survey) <.........................
if form.is_valid():
response = form.save()
return HttpResponseRedirect("/confirm/%s" % response.interview_uuid)
else:
form = ResponseForm(survey=survey)
print form
django_survey\forms.py
def __init__(self, *args, **kwargs):
# expects a survey object to be passed in initially
survey = kwargs.pop('survey')
self.survey = survey
self.user = user <.........................
super(ResponseForm, self).__init__(*args, **kwargs)
self.uuid = random_uuid = uuid.uuid4().hex
# add a field for each survey question, corresponding to the question
# type as appropriate.
data = kwargs.get('data')
It might be worth noting that previously, instead of user, the model's field was called interviewee. I changed this and ran migrations again.
I am also using userena.
The error message in this instance is python trying to tell you that you are attempting to access a variable user that has not been defined in the scope of your method.
Let's look at the first few lines of the __init__() method:
def __init__(self, *args, **kwargs):
# expects a survey object to be passed in initially
survey = kwargs.pop('survey')
self.survey = survey
self.user = user
We can see where the survey variable is defined: survey = kwargs.pop('survey'). It is passed into the form as a keyword argument and extracted in the forms __init__. However underneath you attempt to do the same thing with user but haven't actually defined it above. The correct code would look like:
def __init__(self, *args, **kwargs):
# expects a survey object to be passed in initially
survey = kwargs.pop('survey')
user = kwargs.pop('user')
self.survey = survey
self.user = user
However, this still won't work because we aren't passing the user variable to the form via kwargs. To do that we pass it in when we initialise the form in your views.py. What isn't clear is what user object you are expecting to pass in. the request.user? or does the Survey object have a user attribute? in which case you would not need to pass user in and would just use survey.user etc.
django_survey\views.py
def SurveyDetail(request, id):
survey = Survey.objects.get(id=id)
category_items = Category.objects.filter(survey=survey)
categories = [c.name for c in category_items]
print 'categories for this survey:'
print categories
if request.method == 'POST':
form = ResponseForm(request.POST, survey=survey, user=request.user)
if form.is_valid():
response = form.save()
return HttpResponseRedirect("/confirm/%s" % response.interview_uuid)
else:
form = ResponseForm(survey=survey, user=request.user)
print form
In your view when you initialize your form you need to pass it the user (current user in this case)? similar to this form = ResponseForm(request.POST, survey=survey, user=request.user). Then in the __init__ of your form pop the user object user = kwargs.pop('user'). I believe that will resolve your issue.

int() argument must be a string or a number, not 'QueryDict'

I'm rendering out 3 multiple select boxes on my form.
I'm filtering each box out to have a seperate type of day.
When I submit my form I get this error.
int() argument must be a string or a number, not 'QueryDict'
What must I do to save my form?
This is what i'm doing on my forms.py file to get the different filtering for each select box.
class ContractForm(forms.ModelForm):
def __init__(self, project_id, *args, **kwargs):
super(ContractForm, self).__init__(*args, **kwargs)
self.fields['shoot_day'].queryset = Day.objects.filter(type=SHOOT, project__id=project_id)
self.fields['travel_day'].queryset = Day.objects.filter(type=TRAVEL, project__id=project_id)
self.fields['additional_day'].queryset = Day.objects.filter(type=ADDITIONAL, project__id=project_id)
I'm getting my project_id like so:
def editcontract(request, contract_id, slug):
context_dict = {}
contract = get_object_or_404(Contract, pk=contract_id)
if request.method == 'POST':
form = ContractForm(request.POST, instance=contract)
if form.is_valid():
form.save()
TvUsageForm = TvUsageFormSet(request.POST, instance=contract)
AdditionalMediaUsageForm = AdditionalMediaUsageFormSet(request.POST, instance=contract)
TvUsageForm.save()
AdditionalMediaUsageForm.save()
return HttpResponseRedirect(reverse('contract_list', kwargs={'slug':slug}))
else:
form = ContractForm(instance=contract, project_id=contract.project_id)
TvUsageForm = TvUsageFormSet(instance=contract)
AdditionalMediaUsageForm = AdditionalMediaUsageFormSet(instance=contract)
project = get_object_or_404(Project, slug=slug)
context_dict = { 'form': form,
'tvusage_form':TvUsageForm,
'additional_form':AdditionalMediaUsageForm,
'project':project
}
return render_to_response('contracts/edit_contract.html', context_dict, RequestContext(request))
You have a confusion with the argument list and keyword arguments:
Instead of:
ContractForm(instance=contract, project_id=contract.project_id)
You want:
ContractForm(contract.project_id, instance=contract)
To elaborate: Your constructor accepts the project id as first argument not as keyword argument. Thus you need to give it as first argument. Simple confusion, eh?
Maybe this help you: Adding data to many-to-many field of a modelform within a view

query in django model

I am using django and as I am pretty new I have some questions.
I have one model called Signatures and a ModelForm called SignatureForm in my models.py file:
class Signature(models.Model):
sig = models.ForeignKey(Device)
STATE = models.CharField(max_length=3, choices=STATE_CHOICES)
interval = models.DecimalField(max_digits=3, decimal_places=2)
verticies = models.CharField(max_length=150)
class SignatureForm(ModelForm):
class Meta:
model = Signature
widgets = {
'verticies': HiddenInput,
}
To use it, I wrote the following function in views.py:
def SigEditor(request):
# If the form has been sent:
if request.method == 'POST':
form = SignatureForm(request.POST)
# If it is valid
if form.is_valid():
# Create a new Signature object.
form.save()
return render_to_response('eQL/sig/form_sent.html')
else:
return render_to_response('eQL/sig/try_again.html')
else:
form = SignatureForm()
return render_to_response('eQL/sig/showImage.html', {'form' : form})
However, I don't want to save all the new signatures. I mean, if the user introduces a new signature of the device A and state B, I would like to check if I have some signature like that in my database, delete it and then save the new one so that I have only one signature saved for each device and state.
I have tried something like this before saving it but of course is not working:
q = Signature.objects.filter(sig = s, STATE = st)
if q.count != 0:
q.delete()
form.save()
can anyone help?? thanks!!
If you really do want to delete, why not?
Signature.objects.filter(sig=s, STATE=st).delete()
If you only ever want one combination of those items, you could use get_or_create, and pass in the instance to your ModelForm.
instance, created = Signature.objects.get_or_create(sig=s, STATE=st)
form = SignatureForm(request.POST, instance=signature)
# edit instance.
Or put it in your form save logic:
class SignatureForm(ModelForm):
def save(self, *args, **kwargs):
data = self.cleaned_data
instance, created = Signature.objects.get_or_create(sig=data['sig'], STATE=data['state'])
self.instance = instance
super(SignatureForm, self).save(*args, **kwargs)