Django rest framework custom return response - django

So I have this custom register API which registers a user, but when user successfully register, I want it to have this message "You have successfully register an account!" But I tried a different method but get an error instead.
serializer.py
class UserCreate2Serializer(ModelSerializer):
email = EmailField(label='Email Address')
valid_time_formats = ['%H:%M', '%I:%M%p', '%I:%M %p']
birthTime = serializers.TimeField(format='%I:%M %p', input_formats=valid_time_formats, allow_null=True, required=False)
class Meta:
model = MyUser
fields = ['username', 'password', 'email', 'first_name', 'last_name', 'gender', 'nric', 'birthday', 'birthTime']
extra_kwargs = {"password": {"write_only": True}}
def validate(self, data): # to validate if the user have been used
email = data['email']
user_queryset = MyUser.objects.filter(email=email)
if user_queryset.exists():
raise ValidationError("This user has already registered.")
return data
def create(self, validated_data):
username = validated_data['username']
password = validated_data['password']
email = validated_data['email']
first_name = validated_data['first_name']
last_name = validated_data['last_name']
gender = validated_data['gender']
nric = validated_data['nric']
birthday = validated_data['birthday']
birthTime = validated_data['birthTime']
user_obj = MyUser(
username = username,
email = email,
first_name = first_name,
last_name = last_name,
gender = gender,
nric = nric,
birthday = birthday,
birthTime = birthTime,
)
user_obj.set_password(password)
user_obj.save()
return validated
views.py
class CreateUser2View(CreateAPIView):
permission_classes = [AllowAny]
serializer_class = UserCreate2Serializer
queryset = MyUser.objects.all()
I tried changing this into the serializer
user_obj.set_password(password)
user_obj.save()
content = {'Message': 'You have successfully register an account'}
return content
But got an error instead. I'm unsure how to do the custom response as I only know it is to be done on views.py.
But if I do this on view:
class CreateUser2View(CreateAPIView):
permission_classes = [AllowAny]
serializer_class = UserCreate2Serializer
queryset = MyUser.objects.all()
def post(self, request):
content = {'Message': 'You have successfully register'}
return Response(content, status=status.HTTP_200_OK)
It will show this even if the validation is incorrect. Please help me as I'm still inexperienced in DRF.

class CreateUser2View(CreateAPIView):
permission_classes = [AllowAny]
serializer_class = UserCreate2Serializer
queryset = MyUser.objects.all()
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response({'Message': 'You have successfully register'}, status=status.HTTP_201_CREATED, headers=headers)

from rest_framework import status
from rest_framework.views import exception_handler as base_handler
def exception_handler(exception, context):
"""
Django rest framework for custom exception handler
#exception : Exception
#context : Context
"""
response = base_handler(exception, context)
if response is not None:
response = custom_response(response)
return response
def serializer_errors(data):
"""
Django rest framework serializing the errors
#data : data is python error dictionary
"""
errors = {}
got_msg = False
message = "Bad request."
if isinstance(data, dict):
for key, value in data.items():
try:
if isinstance(value, list):
value = ", ".join(value)
except Exception:
pass
if not got_msg:
if value:
message = value
got_msg = True
errors[key] = value
if not isinstance(message, str):
message = "Bad request"
return errors, message
def error(source, detail, code):
"""
Create python dictionary of error
#source : Where coming the error
#detail : Error detail information
"""
error = {}
error["source"] = source
error["detail"] = detail
if code:
error["code"] = code
return error
def custom_response(response):
"""
Modification the response of django rest framework
#response : Return response
"""
modified_data = {}
modified_data["code"] = response.status_code
modified_data["status"] = get_status(response.status_code)
data, message = serializer_errors(response.data)
modified_data["message"] = message
modified_data["errors"] = data
response.data = modified_data
return response
def get_status(status_code):
"""
Return result base on return http status
#status_code : HTTP status code
"""
result = ""
if status_code == status.HTTP_200_OK:
result = "Success"
elif status_code == status.HTTP_201_CREATED:
result = "Instance create"
elif status_code == status.HTTP_204_NO_CONTENT:
result = "Instance deleted"
elif status_code == status.HTTP_403_FORBIDDEN:
result = "Forbidden error"
elif status_code == status.HTTP_404_NOT_FOUND:
result = "Instance not found"
elif status_code == status.HTTP_400_BAD_REQUEST:
result = "Bad request"
elif status_code == status.HTTP_401_UNAUTHORIZED:
result = "Unauthorized request"
elif status_code == status.HTTP_500_INTERNAL_SERVER_ERROR:
result = "Internal server error"
else:
result = "Unknown error"
return result

Related

How do I fix 'Message' instance needs to have a primary key value before this relationship can be used

When I try to add a Message from the admin pages I get the 'Message' instance needs to have a primary key value before this relationship can be used.
Here is my models.py Message class...
class Message(models.Model):
""" Message as sent through a Submission. """
default_id = time.time()
#adding primary key to satisfy error
id = models.BigAutoField(primary_key=True, auto_created=True)
title = models.CharField(max_length=200, verbose_name=_('title'))
slug = models.SlugField(verbose_name=_('slug'))
newsletter = models.ForeignKey(
Newsletter, verbose_name=_('newsletter'), on_delete=models.CASCADE, default=get_default_newsletter
)
date_create = models.DateTimeField(
verbose_name=_('created'), auto_now_add=True, editable=False
)
date_modify = models.DateTimeField(
verbose_name=_('modified'), auto_now=True, editable=False
)
class Meta:
verbose_name = _('message')
verbose_name_plural = _('messages')
unique_together = ('slug', 'newsletter')
#order_with_respect_to = 'newsletter'
def __str__(self):
try:
return _("%(title)s in %(newsletter)s") % {
'title': self.title,
'newsletter': self.newsletter
}
except Newsletter.DoesNotExist:
logger.warning('No newsletter has been set for this message yet.')
return self.title
def get_next_article_sortorder(self):
""" Get next available sortorder for Article. """
next_order = self.articles.aggregate(
models.Max('sortorder')
)['sortorder__max']
if next_order:
return next_order + 10
else:
return 10
#cached_property
def _templates(self):
"""Return a (subject_template, text_template, html_template) tuple."""
return self.newsletter.get_templates('message')
#property
def subject_template(self):
return self._templates[0]
#property
def text_template(self):
return self._templates[1]
#property
def html_template(self):
return self._templates[2]
#classmethod
def get_default(cls):
try:
return cls.objects.order_by('-date_create').all()[0]
except IndexError:
return None
and the admin.py module
class MessageAdmin(NewsletterAdminLinkMixin, ExtendibleModelAdminMixin,
admin.ModelAdmin):
logger.critical('MessageAdmin')
save_as = True
list_display = (
'admin_title', 'admin_newsletter', 'admin_preview', 'date_create',
'date_modify'
)
list_filter = ('newsletter', )
date_hierarchy = 'date_create'
prepopulated_fields = {'slug': ('title',)}
inlines = [ArticleInline, AttachmentInline, ]
""" List extensions """
def admin_title(self, obj):
return format_html('{}', obj.id, obj.title)
admin_title.short_description = _('message')
def admin_preview(self, obj):
url = reverse('admin:' + self._view_name('preview'), args=(obj.id,),
current_app=self.admin_site.name)
return format_html('{}', url, _("Preview"))
admin_preview.short_description = ''
""" Views """
def preview(self, request, object_id):
logger.critical('preview object_id = %s', object_id)
return render(
request,
"admin/newsletter/message/preview.html",
{'message': self._getobj(request, object_id),
'attachments': Attachment.objects.filter(message_id=object_id)},
)
#xframe_options_sameorigin
def preview_html(self, request, object_id):
logger.critical('preview_html object_id = %s', object_id)
message = self._getobj(request, object_id)
if not message.html_template:
raise Http404(_(
'No HTML template associated with the newsletter this '
'message belongs to.'
))
c = {
'message': message,
'site': Site.objects.get_current(),
'newsletter': message.newsletter,
'date': now(),
'STATIC_URL': settings.STATIC_URL,
'MEDIA_URL': settings.MEDIA_URL
}
return HttpResponse(message.html_template.render(c))
#xframe_options_sameorigin
def preview_text(self, request, object_id):
message = self._getobj(request, object_id)
c = {
'message': message,
'site': Site.objects.get_current(),
'newsletter': message.newsletter,
'date': now(),
'STATIC_URL': settings.STATIC_URL,
'MEDIA_URL': settings.MEDIA_URL
}
return HttpResponse(
message.text_template.render(c),
content_type='text/plain'
)
def submit(self, request, object_id):
submission = Submission.from_message(self._getobj(request, object_id))
change_url = reverse(
'admin:newsletter_submission_change', args=[submission.id])
return HttpResponseRedirect(change_url)
def subscribers_json(self, request, object_id):
message = self._getobj(request, object_id)
json = serializers.serialize(
"json", message.newsletter.get_subscriptions(), fields=()
)
return HttpResponse(json, content_type='application/json')
""" URLs """
def get_urls(self):
urls = super().get_urls()
my_urls = [
path('<object_id>/preview/',
self._wrap(self.preview),
name=self._view_name('preview')),
path('<object_id>/preview/html/',
self._wrap(self.preview_html),
name=self._view_name('preview_html')),
path('<object_id>/preview/text/',
self._wrap(self.preview_text),
name=self._view_name('preview_text')),
path('<object_id>/submit/',
self._wrap(self.submit),
name=self._view_name('submit')),
path('<object_id>/subscribers/json/',
self._wrap(self.subscribers_json),
name=self._view_name('subscribers_json')),
]
return my_urls + urls
I have tried a number of the fixes recommended in posts on this error here in stackoverflow and on github. but none have solved the problem.
I created the id = models.BigAutoField(primary_key=True, auto_created=True) and varified in the sqlite db that the primary key and auto increment are in the structure.
I feel like creating a through or xref table between Message and Article would solve it, but I hesitate because the developers of Jazzband Newsletter (https://github.com/jazzband/django-newsletter) did it this way for a reason and that Django or Python updates have let this creep in.

Django Rest Framework can't identify serializer field name

This is the problem: I have a serializer field pointing to another serializer. I sending an allright request to server and I get this response:
{
"purchase_header": [
"This field is required."
]
}
But the field was sended by POST request (in debugger I can see it).
I finded this code in html.py (from DRF):
def parse_html_dict(dictionary, prefix=''):
"""
Used to support dictionary values in HTML forms.
{
'profile.username': 'example',
'profile.email': 'example#example.com',
}
-->
{
'profile': {
'username': 'example',
'email': 'example#example.com'
}
}
"""
ret = MultiValueDict()
regex = re.compile(r'^%s\.(.+)$' % re.escape(prefix))
for field in dictionary:
match = regex.match(field)
if not match:
continue
key = match.groups()[0]
value = dictionary.getlist(field)
ret.setlist(key, value)
return ret
Well, when debuging I can see that prefix variable contain "purchase_header" and field variable contain the same "purchase_header" string but de match fail returning None. Very rare... dictionary parameter contain all keys and values.
But If you can helpme I appreciate much.
This is the rest of significant code:
urls.py
router = DefaultRouter()
router.register(r'cancel-requests', PurchaseCancellationsRequestViewSet,
basename='purchase-cancel-requests')
router.register(r'invoices', PurchaseViewSet, basename='purchase')
urlpatterns = router.urls
urlpatterns += [path('payment-headers/', PaymentHeadersListAPIView.as_view(
), name='PaymentHeadersListAPIView')]
api.py
class PurchaseViewSet(viewsets.ModelViewSet):
"""
A viewset for viewing and editing purchases instances.
"""
serializer_class = PurchaseSerializer
queryset = Purchase.objects.all().order_by('-created_at')
permission_classes = (IsAuthenticated,)
serializer_action_classes = {
'list': PurchaseSerializer,
'create': PurchaseSerializer,
'retrieve': PurchaseSerializer,
'update': PurchaseSerializer,
'partial_update': PurchaseSerializer,
'destroy': PurchaseSerializer
}
def get_serializer_class(self):
try:
return self.serializer_action_classes[self.action]
except (KeyError, AttributeError):
return super().get_serializer_class()
def get_serializer(self, *args, **kwargs):
serializer_class = self.get_serializer_class()
kwargs["context"] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
def get_list_queryset(self):
try:
store = Store.objects.get(my_owner=self.request.user)
except EmptyResultSet as e:
print("Data Error: {0}".format(e))
urlquery = self.request.GET.get('cancelled', '')
cancelled = False
if urlquery == 'true':
cancelled = True
elif urlquery == '':
# return all
return Purchase.objects.filter(created_for=store)
return Purchase.objects.filter(cancelled=cancelled, created_for=store)
def put(self, request, *args, **kwargs):
if request.user.is_seller:
raise PermissionDenied(
detail='Only owners can cancellate Purchases')
# seller create invoice cancellation request
return self.update(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
request.data['created_by'] = request.user.pk
print(request.data)
if request.user.is_owner is True:
try:
request.data['created_for'] = Store.objects.get(
my_owner=request.user).pk
except Exception as e:
print(e)
return Response(data='User has no Store associated',
status=status.HTTP_400_BAD_REQUEST)
else:
try:
request.data['created_for'] = request.user.seller_profile \
.my_store.pk
except Exception as e:
print(e)
return Response(data='User has no Store associated',
status=status.HTTP_400_BAD_REQUEST)
return self.create(request, *args, **kwargs)
def list(self, request, *args, **kwargs):
# TODO: date ranges
if self.request.user.is_seller:
# TODO: Change -> Indeed the seller can get his own created
# purchases and refactor this to method
raise PermissionDenied(
detail='Only owners can get purchase list.')
queryset = self.get_list_queryset()
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
serializers.py
from rest_framework import serializers
from .models import Purchase, PurchaseCancellationRequest, PurchaseHeader
class PurchaseHeaderSerializer(serializers.ModelSerializer):
class Meta:
model = PurchaseHeader
fields = ['id', 'name']
extra = {
'id': {'read_only': True},
'name': {'read_only': True}
}
class PurchaseSerializer(serializers.ModelSerializer):
purchase_header = PurchaseHeaderSerializer()
class Meta:
model = Purchase
fields = ['id', 'cancelled', 'created_at', 'created_by',
'created_for', 'pic', 'total_amount', 'purchase_header']
extra = {
'cancelled': {'read_only': True},
'created_at': {'read_only': True},
'id': {'read_only': True}
}
def validate_total_amount(self, value):
"""
Sanitize the amount value.
:return: total_amount as float
"""
total_amount = None
try:
total_amount = float(value)
except Exception as e:
print(e)
if total_amount:
return value
else:
raise serializers.ValidationError('Exists an error with '
'total_amount value, probably '
'an empty param or bad float '
'format')
def validate_cancelled(self, value):
"""
Sanitize the cancelled value.
:return: cancelled as python boolean
"""
cancelled = None
try:
cancelled = False if value == 'false' else True
except Exception as e:
print(e)
if cancelled:
return value
else:
raise serializers.ValidationError('Exists an error with '
'cancelled value, probably an '
'empty param or bad boolean '
'value')
def create(self, validated_data):
payment_header_pk = validated_data.pop('purchase_header')
payment_header_obj = PaymentHeader.objects.get(pk=payment_header_pk)
purchase_obj = Purchase.objects.create(
payment_header=payment_header_obj, **validated_data)
return purchase_obj
class PurchaseCancellationRequestSerializer(serializers.ModelSerializer):
class Meta:
model = PurchaseCancellationRequest
fields = ['purchase']
models.py
class PurchaseHeader(SoftDeleteModel):
name = models.CharField(max_length=50)
city = models.ManyToManyField(City, through='purchases.ProviderCity')
created_at = models.DateTimeField(default=timezone.now(), editable=False)
modified_at = models.DateTimeField(default=timezone.now())
class ProviderCity(SoftDeleteModel):
city = models.ForeignKey(City, on_delete=models.PROTECT)
purchase_header = models.ForeignKey(PurchaseHeader,
on_delete=models.PROTECT)
class Meta:
unique_together = ('city', 'purchase_header')
Thank for all friends!!

Django BuiltinSignatureError when using DRF

I am not able to figure out the error. The API sometimes returns data and at times it does not.
class CreateQuiz(generics.ListCreateAPIView):
serializer_class = QuizSerializer
def get_queryset(self):
classId = self.kwargs.get('classId',None)
subject = self.kwargs.get('subject',None)
category = Category.objects.filter(class_id=classId,category=subject).values_list('id',flat=True)[0]
# chapter = self.kwargs.get('chapter',None)
subcategory=self.kwargs.get('chapter',None)
subcat = SubCategory.objects.filter(id=subcategory).values_list('sub_category',flat=True)[0]
total_marks = 30
questionIDs = Question.objects.raw('''somesql''',params=[category,subcategory,total_marks,category,subcategory,total_marks])
#
# and qq.sub_category_id IN %s
questions= MCQuestion.objects.filter(question_ptr_id__in=questionIDs).prefetch_related('answer_set__question')
essayquestions= Essay_Question.objects.filter(question_ptr_id__in=questionIDs)
user = User.objects.get(id=1)
if MCQuestion.objects.filter(question_ptr_id__in=questionIDs).prefetch_related('answer_set__question').exists():
print("create quiz")
quiz = Quiz()
quiz.durationtest="10:00"
quiz.random_order=True
quiz.save()
quizid = Quiz.objects.filter(id=quiz.id).values_list('id',flat=True)[0]
quiz = Quiz.objects.get(id=quiz.id)
quiz.title = "Practice Exam : "+ quiz.category.class_id.classVal +" "+quiz.category.category +" ("+subcat+") "
quiz.save()
with connection.cursor() as cursor:
cursor.execute("INSERT INTO quiz_subcategory_quiz(subcategory_id,quiz_id) VALUES (%s,%s)",(subcategory,quiz.id,))
for obj in questionIDs:
if Question.objects.filter(id=obj.id,quiz__id=quiz.id).exists():
print("Do nothing")
else:
question = Question(id=obj.id)
question.quiz.add(quiz.id)
question.save()
obj, created = UserQuiz.objects.update_or_create(
user_id = user.id,quiz_id=quiz.id
)
return Quiz.objects.filter(id=quizid)
else:
response = JsonResponse({"error": "there was an error"})
response.status_code = 403 # To announce that the user isn't allowed to publish
return response
return Quiz.objects.filter(id=quizid)
My Serializer Class
class QuizSerializer(serializers.ModelSerializer):
class Meta:
model = Quiz
fields=(
'id',
'title',
'description',
'url',
'category',
'random_order',
'pass_mark',
'draft',
'durationtest',
)
I get the following error and its happening randomly. Any suggestions please.
Field source for QuizSerializer.title maps to a built-in function type and is invalid. Define a property or method on the bytes instance that wraps the call to the built-in function.

Uploaded Model Data WIth DRF Data Does Not Save

I'm trying to upload a photo along with other data for my CustomerDetails model via an api endpoint. The data seems to save but, when I check my table, there is no data present.
Here is my model:
class CustomerDetails(models.Model):
Sizes = (
('Sizes', (
('small', 'small'),
('medium', 'medium'),
('large', 'large'),
)),
)
CATEGORIES = (
('Usage', (
('Headache', 'Headache'),
('Backaches', 'Insomnia'),
('Menstrual Cramps & Pains','Menstrual Cramps
)),
)
CUSTYPE = (
('Customer Type',(
('Athlete', 'Athlete'),
('Non-Athlete', 'Non-Athlete'),
)),
)
age = models.IntegerField(default="21", blank=True)
nick_name = models.CharField(max_length=500, blank=True)
average_order = models.FloatField(default = "0.0", blank=True)
completed_orders = models.IntegerField(default = "0", blank=True)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='customer')
customer_type = MultiSelectField(choices=CUSTYPE, default = CUSTYPE, max_length=100)
current_selfie = models.ImageField(upload_to= 'sefies/', blank=True, default='')
favorite_color = MultiSelectField(choices=TYPE, max_length=100)
interested_in = MultiSelectField(choices=CATEGORIES, max_length=1000)
last_signin = models.DateTimeField(default = timezone.now)
liked_stores = models.ManyToManyField('Stores')
liked_products = models.ManyToManyField('Product')
phone = PhoneField(blank=True, help_text='Contact phone number')
shares = models.IntegerField(default = "0", blank=True)
signup = models.DateTimeField(default = timezone.now)
def __str__(self):
return self.customer.user.get_full_name()
Here are my serializers & Url
url(r'^api/customer/create_customer_details/$', apis.CustomerDetailViewset.as_view()),
class CustomerDetailUploader(serializers.ModelSerializer):
customer = CustomerDetailSerializer()
current_selfie = serializers.SerializerMethodField()
def get_current_selfie(self, store):
request = self.context.get('request')
current_selfie_url = CustomerDetails.current_selfie.url
return request.build_absolute_uri(current_selfie_url)
class Meta:
model = CustomerDetails
fields = ('nick_name', 'customer', 'current_selfie', 'favorite_color', 'interested_in', 'customer_type')
Here is the apiView I'm using:
class CustomerDetailViewset(APIView):
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
file_serializer = CustomerDetailUploader(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I'm trying to create a new customerDetails page for every user when they sign up, assign the data to a Customer, and save the details. Everytime I try to call the function, I do get the success message:
[15/Feb/2019 22:56:10] "POST /api/customer/create_customer_details/?access_token=U3EvAbo1HhOwNAgcEYUR4WOegul6ye HTTP/1.1" 201 99
Can anyone let me know how I can fix this?
You can try this save image (Base64) using DRF
serializer.py
class Base64ImageField(serializers.ImageField):
def to_internal_value(self, data):
from django.core.files.base import ContentFile
import base64
import six
import uuid
# Check if this is a base64 string
if isinstance(data, six.string_types):
# Check if the base64 string is in the "data:" format
if 'data:' in data and ';base64,' in data:
# Break out the header from the base64 content
header, data = data.split(';base64,')
# Try to decode the file. Return validation error if it fails.
try:
decoded_file = base64.b64decode(data)
except TypeError:
self.fail('invalid_image')
# Generate file name:
file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough.
# Get the file name extension:
file_extension = self.get_file_extension(file_name, decoded_file)
complete_file_name = "%s.%s" % (file_name, file_extension, )
data = ContentFile(decoded_file, name=complete_file_name)
return super(Base64ImageField, self).to_internal_value(data)
def get_file_extension(self, file_name, decoded_file):
import imghdr
extension = imghdr.what(file_name, decoded_file)
extension = "jpg" if extension == "jpeg" else extension
return extension
class CustomerDetailUploader(serializers.ModelSerializer):
customer = CustomerDetailSerializer()
current_selfie = Base64ImageField()
class Meta:
model = CustomerDetails
fields = ('nick_name', 'customer', 'current_selfie', 'favorite_color', 'interested_in', 'customer_type')
in api.py
class CustomerDetailViewset(APIView):
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
file_serializer = CustomerDetailUploader(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Reponse ({})
hope it help for your problem
Maybe you have some errors, but you are not seeing them, because you're return always 201. The first Response should be inner the if branch.
Your code:
def post(self, request, *args, **kwargs):
file_serializer = CustomerDetailUploader(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
correct code:
def post(self, request, *args, **kwargs):
file_serializer = CustomerDetailUploader(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Django queryset calling only objects belonging to User

I'm unable to figure out how to only call a queryset of items that belong to a specific User in the django forms.
dropoffs/models.py
class DropoffItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
dropoff = models.ForeignKey('Dropoff', null=True, blank=True)
product = models.ForeignKey(Product)
location = models.CharField(max_length=120, choices=LOCATION_CHOICES, default="Customer")
def __str__(self):
return str('%s' + " " + "(" + '%s' + ")") %(self.product.title, self.product.sku)
def sku(self):
return self.product.sku
def title(self):
return self.product.title
def dropoff_id(self):
return str(self.dropoff.id)
forms.py
class AddPickupItemForm(forms.ModelForm):
dropoffitem = forms.ModelChoiceField(queryset=DropoffItem.objects.none())
class Meta:
model = PickupItem
# fields = ["product", "quantity"]
fields = ['dropoffitem']
def __init__(self, user, *args, **kwargs):
# self.request = kwargs.pop("request")
the_user = kwargs.pop('user', None)
super(AddPickupItemForm, self).__init__(*args, **kwargs)
if the_user is not None:
self.fields["dropoffitem"].queryset = DropoffItem.objects.filter(user=the_user)
views.py
def add_item_to_pickup_order(request):
request.session.set_expiry(120000)
try:
user = request.user
the_id = request.session['pickup_id']
pickup = Pickup.objects.get(id=the_id)
except:
user = request.user
new_pickup_order = Pickup(user=user)
new_pickup_order.save()
request.session['pickup_id'] = new_pickup_order.id
the_id = new_pickup_order.id
pickup = Pickup.objects.get(id=the_id)
try:
dropoffitem = DropoffItem.objects.filter(user=user)
except DropoffItem.DoesNotExist:
pass
except:
pass
form = AddPickupItemForm(request.POST, user=request.user)
if request.method == "POST":
dropoffitem_id = int(request.POST['dropoffitem'])
pickup_item = PickupItem.objects.create(pickup=pickup, dropoffitem_id=dropoffitem_id)
pickup_item.save()
return HttpResponseRedirect('%s'%(reverse('add_item_to_pickup_order')))
context = {
"pickup": pickup,
"form": form,
}
return render(request, 'pickups/create_pickup_order.html', context)
With the modifications to init, I'm getting a TypeError of: init() got multiple values for keyword argument 'user'.
Could that be because of how I'm requesting a 'session'?
class AddPickupItemForm(ModelForm):
def __init__(self,*args,**kwargs)
the_user = kwargs.pop('user',None)
super(AddPickupItemForm, self).__init__(*args,**kwargs)
if the_user is not None:
self.fields['dropoffitem'].queryset = DropOffItem.objects.filter(user=the_user)
In other words, pass your user to the form when instantiating, if you need to.