django add pdf to a request value - django

in the following request I receive a total of 10 pdfs which I must combine in one document
once this is done I have to upload it to the client model which stores the files in aws s3, once I pass the file with all the pdfs together it gives me the following error
{
"error": true,
"message": {
"documents": [
"The submitted data was not a file. Check the encoding type on the form."
]
}
}
this is mi code
merger = PdfFileMerger()
for x in request.FILES:
print(request.FILES[x])
merger.append(request.FILES[x])
merger.write(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'media/' + str(getUser.id) + '.pdf'))
merger.close()
pdf = open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'media/' + str(getUser.id) + '.pdf'), 'rb')
# set the client Data
clientData = {
'type_client': request.data['type_client'],
'type_identity': request.data['type_identity'],
'document_number': request.data['document_number'],
'first_name': request.data['first_name'] if 'first_name' in request.data else None,
'last_name': request.data['last_name'] if 'last_name' in request.data else None,
'social_reason': request.data['social_reason'] if 'social_reason' in request.data else None,
'address': request.data['address'],
'city': request.data['city'],
'email': request.data['email'],
'phone_number': request.data['phone_number'],
'ciiu': request.data['ciiu'],
'broker': request.data['broker'],
'user': getUser.id,
'documents': pdf,
'status': 0,
'income': request.data['income'],
'entered_by': request.user.id
}
# Create a new client
client = ClientSerializer(data=clientData)
this is my model
from django.db import models
# Relations
from apps.misc.models import City, TypeIdentity, TypeCLient, CIIU
from apps.clients.api.models.broker.index import Broker
from apps.authentication.api.models.user.index import User
class Client(models.Model):
id = models.CharField(max_length=255, unique=True,primary_key=True, editable=False)
type_client = models.ForeignKey(TypeCLient, on_delete=models.CASCADE, blank=True)
type_identity = models.ForeignKey(TypeIdentity, on_delete=models.CASCADE, blank=True)
document_number = models.CharField(max_length=255, blank=True, unique=True)
first_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255, blank=True, null=True)
social_reason = models.CharField(max_length=255, blank=True, null=True)
city = models.ForeignKey(City, on_delete=models.CASCADE, blank=True)
address = models.CharField(max_length=255, blank=True)
email = models.CharField(max_length=255, blank=True, unique=True)
phone_number = models.CharField(max_length=255, blank=True, unique=True)
ciiu = models.ForeignKey(CIIU, on_delete=models.CASCADE, blank=True)
broker = models.ForeignKey(Broker, on_delete=models.CASCADE, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
documents = models.FileField(upload_to='documents/')
income = models.SmallIntegerField(blank=True, default=0)
entered_by = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, related_name='entered_by')
state = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True, default=None)
class Meta:
db_table = 'clients'
verbose_name = 'clients'
verbose_name_plural = 'clients'
ordering = ['created_at']
as you can see in the documents property of the clientData dict I assign the combined pdf previously, is there any way to solve this?

Related

get the related records in a serializer - django

I am trying to obtain in a query the data of a client and the contacts he has registered I tried to do it in the following way but it did not work.
class ClientReadOnlySerializer(serializers.ModelSerializer):
clientcontacts = ClientContactSerializer(many=True, read_only=True)
class Meta:
model = Client
fields = "__all__"
Is there any way to make this relationship nested?
these are my models
clients model
# Relations
from apps.misc.models import City, TypeIdentity, TypeCLient, CIIU
from apps.clients.api.models.broker.index import Broker
from apps.authentication.models import User
class Client(models.Model):
id = models.CharField(max_length=255, unique=True,primary_key=True, editable=False)
type_client = models.ForeignKey(TypeCLient, on_delete=models.CASCADE, blank=True)
type_identity = models.ForeignKey(TypeIdentity, on_delete=models.CASCADE, blank=True)
document_number = models.CharField(max_length=255, blank=True, unique=True)
first_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255, blank=True, null=True)
social_reason = models.CharField(max_length=255, blank=True, null=True)
city = models.ForeignKey(City, on_delete=models.CASCADE, blank=True)
address = models.CharField(max_length=255, blank=True)
email = models.CharField(max_length=255, blank=True, unique=True)
phone_number = models.CharField(max_length=255, blank=True, unique=True)
ciiu = models.ForeignKey(CIIU, on_delete=models.CASCADE, blank=True)
broker = models.ForeignKey(Broker, on_delete=models.CASCADE, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
income = models.SmallIntegerField(blank=True, default=0)
state = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True, default=None)
client contacts model
# Relations
from apps.clients.api.models.index import Client
class ClientContact(models.Model):
id = models.CharField(max_length=255, primary_key=True, unique=True, editable=False)
client = models.ForeignKey(Client, on_delete=models.CASCADE)
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
phone_number = models.CharField(max_length=255)
state = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True, blank=True, default=None)
after some research I came up with a solution that doesn't seem very practical, what I did was to create a method in the serializer that queries the client's contacts as follows
class ClientReadOnlySerializer(serializers.ModelSerializer):
contacts = serializers.SerializerMethodField(method_name='get_contacts')
class Meta:
model = Client
fields = "__all__"
extra_fields = ['contacts']
def get_contacts(self, obj):
contacts = ClientContact.objects.filter(client=obj)
serializer = ClientContactSerializer(contacts, many=True)
return serializer.data
using the model and the serializer of the contact model I made a query which I added in an extra field of the customer serializer, if someone knows how to make this process more optimal please reply.

I receive an error while migrating my models to a database

I get such an error while migrating to a database:
return Database.Cursor.execute(self, query)
django.db.utils.OperationalError: foreign key mismatch - "user_auth_customer"
referencing "user_auth_profile"
I have checked Foreign_Keys of my models and they look good.
I have no idea why I receive that error :(
Please, help me out here.
class Customer(AbstractUser):
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
profile = models.OneToOneField("Profile", related_name="user_profile",
on_delete=models.CASCADE, null=True)
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, null=True, blank=True)
username = models.CharField(max_length=30, null=True, blank=True)
phone = models.CharField(max_length=10, default='', null=True, blank=True)
email = models.EmailField(validators=[validators.EmailValidator()],
unique=True)
password = models.CharField(max_length=100, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
#staticmethod
def get_customer_by_email(email):
try:
return Customer.objects.get(email=email)
except:
return False
def isExists(self):
if Customer.objects.filter(email=self.email):
return True
return False
class Meta:
verbose_name = 'Customer'
verbose_name_plural = 'Customers'
class Profile(models.Model):
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, null=True, blank=True)
phone = models.CharField(max_length=10, default='', null=True, blank=True)
email = models.EmailField(primary_key=True, unique=True, validators=[validators.EmailValidator()])
password = models.CharField(max_length=100, null=True, blank=True)
# Add a photo field
owner = models.OneToOneField(Customer, related_name='profile_owner',
on_delete=models.SET_NULL, null=True)
username = models.CharField(max_length=30, null=True, blank=True,
validators=[UnicodeUsernameValidator()])
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Profile'
verbose_name_plural = 'Profiles'
if you need any else details, I can provide you with those in the comments.
You can't have both ways OneToOneField. Choose one way.
If you delete Customer's profile field, then still you will have possibility to call relation with:
customer = Customer.objects.get(id=1)
customer.profile # that will call Customer's related Profile object
Assuming, that you will change related_name='profile_owner' to simpler related_name='profile'.
Read more about OneToOneRelationships.

DRF error create() got multiple values for keyword argument 'hnid'

so I am building a pet blog project where my scenario is - my users will be able to post multiple images and audios if they want while doing so , am facing several problems -
while trying to post through POSTMAN . I am getting an error saying create() got multiple values for keyword argument 'hnid' ..
while querying using UUID , it is throwing , a String naming "HNUsers object (e3ec1a43-ebc4-47b9-bf2f-55967af8ea71)" where I just wanted UUID(e3ec1a43-ebc4-47b9-bf2f-55967af8ea71) but came with extra HNUsers object
Here is my Profile model
class HNUsers(models.Model):
USERTYPE = (
(u'RU', u'REGULAR USER'),
(u'HN', u'HN'),
)
GENDER = (
(u'M', u'Male'),
(u'F', u'Female'),
(u'O', u'Other'),
)
ip_address = models.CharField("IP Address" , max_length=100, blank=True, null=True)
full_name = models.CharField("Full Name", max_length=100, null=True, blank=True)
username = models.CharField("Username", max_length=100, null=True, blank=True)
email = models.EmailField("Email", blank=True, null=True)
user_type = models.CharField("User Type", max_length=2, choices=USERTYPE, null=True, blank=True, default=USERTYPE[0][0])
mobile_number = models.CharField("Mobile Number", max_length=20, blank=True, null=True)
date_of_birth = models.DateField("Date of Birth", auto_now_add=False, blank=False, null=True)
gender = models.CharField("Gender", max_length=1, choices=GENDER, blank=True, null=True, )
registration_date = models.DateTimeField("Registration Date", auto_now_add=True, null=True, blank=True)
city = models.CharField("City", max_length=50, blank=True, null=True)
country = models.CharField("Country", max_length=50, blank=True, null=True)
profile_img = models.ImageField("Profile Image", blank=True, null=True)
first_img = models.FileField("First Image", blank=True, null=True)
first_img_url = models.CharField("First Image Url", blank=True, null=True, max_length=500)
profile_img_url = models.CharField("Profile Image Url", blank=True, null=True, max_length=500)
hnid = models.UUIDField("HNID", default=uuid.uuid4, unique=True, primary_key=True, editable=False)
my imagepost model
class ImagePost(models.Model):
hnid = models.ForeignKey("profiles.HNUsers", on_delete=models.DO_NOTHING)
file = models.FileField("Image", blank=True, null=True)
timestamp = models.DateTimeField("Timestamp", blank=True, null=True, auto_now_add=True)
text = models.TextField("Description text", blank=True)
class Meta:
verbose_name_plural = "Image Posts"
serializer for image post
class MultiMediaSerializer(serializers.ModelSerializer):
file = serializers.ListField(child=serializers.FileField(max_length=100, allow_empty_file=False, use_url=True))
def create(self, validated_data):
request = self.context.get('request')
# print(validated_data)
files = validated_data.pop('file')
print(files)
user = HNUsers.objects.get(pk=request.data['hnid'])
print("hnid ", user)
# print("hnid ", entry)
for img in files:
print(img)
photo = ImagePost.objects.create(file=img, hnid=user, **validated_data)
return photo
class Meta:
model = ImagePost
fields = ('hnid', 'file',)
Views.py file for the above is -
#api_view(['POST'])
#permission_classes((permissions.AllowAny,))
#parser_classes([MultiPartParser, FormParser])
def posting_api(request):
if request.method == 'POST':
data = request.data
print(data)
serializer = MultiMediaSerializer(data=data, context={'request': request})
if serializer.is_valid():
serializer.save()
print("image object saved")
return Response(serializer.data, status=status.HTTP_201_CREATED)
Sorry I am new to this
Remove hnid=user from the create statement since the validated_data does have the hnid field already
photo = ImagePost.objects.create(file=img, **validated_data)

How to reference ForeignKey objects in HTTP POST?

I have a RESTful API on Django and I would like to know how to reference an existing ForeignKey when using json in HTTP POST?
class Trainer(models.Model):
account = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='profiles')
username = models.CharField(max_length=30, unique=True, primary_key=True)
start_date = models.DateField(default=date(2016,7,13), null=True, blank=True)
faction = models.ForeignKey('Faction', on_delete=models.SET_DEFAULT, default=0, null=True, verbose_name="team")
has_cheated = models.BooleanField(default=False)
last_cheated = models.DateField(null=True, blank=True)
currently_cheats = models.BooleanField(default=False)
statistics = models.BooleanField(default=True)
daily_goal = models.IntegerField(null=True, blank=True)
total_goal = models.IntegerField(null=True, blank=True)
last_modified = models.DateTimeField(auto_now=True)
prefered = models.BooleanField(default=True, verbose_name="main profile")
def __str__(self):
return self.username
class Faction(models.Model):
name = models.CharField(max_length=140)
colour = RGBColorField(default='#929292', null=True, blank=True)
image = models.ImageField(upload_to=factionImagePath, blank=True, null=True)
leader_name = models.CharField(max_length=140, null=True, blank=True)
leader_image = models.ImageField(upload_to=leaderImagePath, blank=True, null=True)
def __str__(self):
return self.name
This are the relevant models, I have a list of 4 Faction objects, with their primary keys being 0, 1, 2 and 3.
I've tried many different way, but I just can't figure it out.
This was my latest try, can you advice where I'm going wrong?
{
"username": "Bob123",
"faction": "1"
}
Returned
{
"username": "Bob123",
"faction": "Teamless",
"start_date": "2016-07-13",
"has_cheated": false,
"last_cheated": null,
"currently_cheats": false,
"statistics": true,
"daily_goal": null,
"total_goal": null,
"last_modified": "2017-09-08T21:05:18.001389Z",
"prefered": true,
"account": null
}
Edit: My friend helped me with the solution, I had faction = serializers.StringRelatedField() in the serializer for Trainer, which is Read-only.
My friend helped me with the solution, I had 1faction = serializers.StringRelatedField()1 in the serializer for Trainer, which is Read-only.

django send mail recipient-list

I have a model form that is basically a job ticket. The save method in the view is set to send an email notification on save. The model has a couple of fields that inherit from a parent UserProfile model:
class RemoteRequest(models.Model):
create_date = models.DateTimeField(auto_now_add=True)
requested_by = models.ForeignKey(UserProfile)
client = models.CharField(max_length=50, choices=CLIENT_CHOICES)
job_number = models.CharField(max_length=8, unique=False, blank=False, null=False)
cell_number = models.CharField(max_length=4, unique=False, blank=True, null=True)
job_name = models.CharField(max_length=200, unique=False, blank=True, null=True)
print_request = models.ManyToManyField(PrintRequest, unique=False, blank=True, null=True)
interactive_request = models.ManyToManyField(InteractiveRequest, unique=False, blank=True, null=True)
due_date = models.DateTimeField(auto_now_add=False)
job_notes = models.TextField(max_length=500, unique=False, blank=True, null=True)
asset_location = models.CharField(max_length=300, unique=False, blank=True, null=True)
asset_upload = models.FileField(upload_to=request_file_name, blank=True, null=True, max_length=300)
pdf_upload = models.FileField(upload_to=request_file_name, blank=True, null=True, max_length=300)
*notify_internal = models.ManyToManyField(UserProfile, related_name='+', unique=False, blank=True, null=True)*
notify_external = models.ManyToManyField(FreelanceProfile, unique=False, blank=True, null=True)
completed_by = models.ForeignKey(UserProfile, related_name='+', blank=True, null=True)
complete_date = models.DateTimeField(auto_now_add=False, blank=True)
asset_return = models.FileField(upload_to=return_file_name, blank=True, null=True, max_length=300)
pdf_return = models.FileField(upload_to=return_file_name, blank=True, null=True, max_length=300)
return_notes = models.TextField(max_length=500, unique=False, blank=True, null=True)
def __unicode__ (self):
return u'%s %s %s %s %s' % (self.client, self.job_number, '-', self.cell_number, self.job_name)
the UserProfile model has an email field. This is what I'm trying to pass to the recipient list in the view:
def remote_request(request):
if request.method=='POST':
form = RemoteRequestForm(request.POST)
if form.is_valid():
name = form.cleaned_data['job_name']
subject = form.cleaned_data['job_name']
message = form.cleaned_data['job_notes']
sender = form.cleaned_data['requested_by']
recipients = [form.cleaned_data['**notify_internal.userprofile.email**']]
from django.core.mail import send_mail
send_mail(subject, message, sender, recipients)
remoterq = form.save(commit=False)
remoterq.save()
form.save_m2m()
return render(request, 'remote_tmps/remoterequest.html', {'form': form,
})
else:
form = RemoteRequestForm()
return render(request, 'remote_tmps/remoterequest.html', {'form': form,})
Unfortunately "notify_internal.userprofile.email" throws a key error and I'm at a loss as to how to properly pass these email recipients.
What makes you think passing a string with python dot notation would do something special in the dictionary lookup?
You're saving your object, so just pull the recipients after you save, after save m2m().
recipients = [user.email for user in remoterq.notify_internal.all()]
Look at the ManyToManyField docs to see how to get data. There's a QuerySet interface exposed in the field attribute.