Django Rest Framework Post API Method Not Working - django

I am new to DRF and am trying to create four basic API methods for my Company model. GET, PUT, and DELETE are working fine. However, I am having issue with POST. When I test it with Postman it "kinda" saves the object in the Database, but with null values and not with ones that I entered. Only values that it saves that are not null are ID (which is saved automatically by default) and image field because I set the default image.
I am using PostgreSQL DB, and below are my models.py, serializers.py, views.py, and urls.py.
models.py
`#Companies
#File Location Function
def upload_location(instance, filename, **kwargs):
file_path = 'company/{company_name}-{filename}'.format(
company_name = str(instance.name),
filename = filename
)
return file_path
class Companies(models.Model):
STATUS = (
("Active", "Active"),
("Inactive", "Inactive")
)
#Basic fields
code = models.CharField(max_length=30, unique=True, null=True, verbose_name="Company Code ")
name = models.CharField(max_length=100, unique=True, verbose_name='Company Name ', null=True)
address = models.CharField(max_length=100, unique=True, verbose_name='Address ', blank=True, null=True)
city = models.CharField(max_length=100, verbose_name='City ', blank=True, null=True)
zip_code = models.CharField(max_length=10, verbose_name='Zip Code ', blank=True, null=True)
country = models.CharField(max_length=100, verbose_name='Country ', blank=True, null=True)
default_email = models.CharField(max_length=100, unique=True, verbose_name='Default E-mail ', blank=True, null=True)
default_phone = models.CharField(max_length=100, unique=True, verbose_name='Default Phone Number ', blank=True, null=True)
id_number = models.IntegerField(unique=True, verbose_name='ID Number ', blank=True, null=True)
tax_number = models.IntegerField(unique=True, verbose_name='Tax Number ', blank=True, null=True)
status = models.CharField(max_length=20, null=True, choices=STATUS, verbose_name='Actvity Status ', help_text='Choose from a dropdown list. ', blank=True)
description = RichTextField(blank=True, verbose_name='Company`s Activities ', null=True)
image = models.ImageField(default='default_company_image.jfif', upload_to=upload_location, blank=True, verbose_name='Company Image ', help_text='If not uploaded, the default company-image will be set. Not required field.', null=True)
#Utility field
date_created = models.DateTimeField(auto_now_add=True, verbose_name="Date of Entry in DB")
date_updated = models.DateTimeField(auto_now=True, verbose_name="Date of Entry`s Update in DB")
slug = models.SlugField(blank=True, unique=False, verbose_name="URL Snippet ", help_text="Automatically Created.")
class Meta:
verbose_name = 'Company'
verbose_name_plural = 'Companies'
#Object representation
def __str__(self):
return f'{self.name} in {self.country}'`
serializers.py
`#Companies Serializer
class CompaniesSerializer(serializers.ModelSerializer):
class Meta:
model = Companies
fields = '__all__'`
views.py
`#Create company object in DB through API
#api_view(['POST',])
def create_company(request):
serializer = CompaniesSerializer(data=request.data)
if request.method == "POST":
if serializer.is_valid(raise_exception=True):
company_saved = serializer.save()
return Response({"success": "Company '{}' created successfully".format(company_saved.name)})`
urls.py
`urlpatterns = [
...
path('create_company/', views.create_company, name="create_company"),
...
]`

You have to keep request.method == "POST" before serializer
#api_view(['POST'])
def create_company(request):
if request.method == "POST":
serializer = CompaniesSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
company_saved = serializer.save()
return Response({"success": "Company '{}' created successfully".format(company_saved.name)})`

Related

django form is not picking data which is already in database

How do I update my form as the
form.instance.users = request.user
is not working however if I print request.user on terminal it prints the username of the user currently logged in.
Also in this form I want to pick existing data from that user to display in the form to update it.
The save form button return HttpResponse saved successfully but the data is not stored in the database.
models.py
class BasicDetails(models.Model):
GENDERS = (
('M', 'Male'),
('F', 'Female'),
('O', 'Others'),
)
users = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, blank=True, null=True)
father_name = models.CharField(max_length=50, blank=True, null=True)
mother_name = models.CharField(max_length=50, blank=True, null=True)
date_of_birth = models.DateField(blank=True, null=True)
gender = models.CharField(max_length=1, choices=GENDERS)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.first_name+" "+ self.last_name
class Education(BasicDetails):
current_year = datetime.date.today().year
YEAR_CHOICES = [(r, r) for r in range(2000, datetime.date.today().year+2)]
course_name = models.CharField(max_length=100, blank=True, null=True)
university_board_name = models.CharField(
max_length=200, blank=True, null=True)
passing_year = models.IntegerField(
choices=YEAR_CHOICES, default=current_year, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(default=timezone.now)
forms.py
class BasicDetailsForm(forms.ModelForm):
class Meta:
model = BasicDetails
fields = '__all__'
exclude = ['users']
class EducationForm(forms.ModelForm):
class Meta:
model = Education
fields = '__all__'
exclude = ['users']
views.py
#login_required
def View(request):
education = EducationForm()
education.instance.users = request.user
if request.method =="POST":
print(request.user.id)
education = EducationForm(request.POST,instance=request.user)
if education.is_valid():
education.save(commit=True)
return HttpResponse("Saved Successfully")
else:
education = EducationForm()
return render(request, 'app/view.html',{'education':education})

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)

Django ManyToManyField not showing in admin

As this questions says, I am having trouble displaying a ManyToManyField in the django admin page.
The m2m field that I'm having trouble displaying is comics in the Gig model.
Here is the code for my project:
#models.py file
class Host(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='host')
name = models.CharField("Venue Name", max_length=200)
slug = models.SlugField(allow_unicode=True, blank=True, null=True)
description = models.TextField("Brief Venue Description - [50 Characters Max]", max_length=50, blank=True)
profile_pic = models.ImageField("Profile Picture", upload_to='host/profile_pics',blank=True)
class Gig(models.Model):
host = models.ForeignKey(Host, on_delete=models.CASCADE, blank=True, related_name='host_gigs')
title = models.CharField("Gig Title",max_length=50, null=True)
date_time = models.DateTimeField("Date/Time of Gig", null=True, blank=True)
description = models.TextField("Describe this gig", max_length=150, blank=True)
instructions = models.CharField('Instructions for accepted comics', max_length=200, blank=True, null=True)
comics = models.ManyToManyField("comic.Comic", through='comic.ComicGig',related_name='gig_comics', default=" ")
#in separate app
#models.py
class Comic(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE, related_name='comic')
dob = models.DateField("Date of Birth", null=True, blank=True)
mobile = PhoneNumberField(null=True, blank=True)
slug = models.SlugField(allow_unicode=True, blank=True, null=True)
class ComicGig(models.Model):
thegig = models.ForeignKey('host.Gig', on_delete=models.CASCADE, default="", related_name='comic_gig')
comic = models.ForeignKey(Comic, on_delete=models.CASCADE, default="")
approved_comic = models.BooleanField(default=False, null=True)
def approve(self):
self.approved_comic = True
self.save()
Here is my Host admin.py file:
class AuthorAdmin(admin.ModelAdmin):
list_display = ('host', 'title',)
filter_horizontal = ('comics',)
def formfield_for_manytomany(self, db_field, request, **kwargs):
if db_field.name == "comics":
kwargs["queryset"] = Gig.objects.filter(comic_gig__approved_comic=True)
return super().formfield_for_manytomany(db_field, request, **kwargs)
admin.site.register(Host)
admin.site.register(Gig, AuthorAdmin)
Here is a picture of my Host model in the admin
Here is a picture of my ComicGig model in the admin

replacing dropdown lookup with related user field

In a form I have a drop down of usernames, this is referenced in the 'taken_by' field. I would like to display first_name and last_name, this is achieved through the __str__ but I can't seem to get it to function, the list of usernames are presented but not the firstname. Suggestions welcome.
from django.contrib.auth.models import User
from django.conf import settings
class Sample(models.Model):
sample_id = models.AutoField(primary_key=True)
area_easting = models.IntegerField(choices = EASTING_CHOICES)
area_northing = models.IntegerField(choices = NORTHING_CHOICES)
context_number = models.IntegerField()
sample_number = models.IntegerField()
material_type = models.CharField(max_length=200, default='', blank=True, null=True, choices = MATERIALS)
weight = models.DecimalField(max_digits=6, decimal_places=2)
description = models.CharField(max_length=500, default='', blank=True, null=True)
recovery_method = models.CharField(max_length=200, default='', blank=True, null=True, choices = RECOVERY_METHODS)
taken_by = models.ForeignKey(settings.AUTH_USER_MODEL, db_column='taken_by', on_delete = models.PROTECT)
comments = models.CharField(max_length=1000, default='', blank=True, null=True)
def __str__(self):
return self.taken_by.first_name
# return str(self.sample_id)
# return str(self.firstname)+ '-' +str(self.lastname)
# return u'%s %s' % (self.first_name, self.last_name)
Form setup as requested
class BotanySampleFilterForm(forms.ModelForm):
class Meta:
model = Sample
fields = (
# 'botany_id',
'sample_id',
'area_easting',
'area_northing',
'context_number',
'sample_number',
'material_type',
'weight',
'description',
'recovery_method',
'taken_by',
'comments'
)

Django: How to show user owned data in Admin forms

Following are the models of my app:
class Store(models.Model):
store_owner = models.ForeignKey(User, null=False, verbose_name='User')
store_name = models.CharField(max_length=200, null=False,
verbose_name='Store name')
store_address_line_1 = models.CharField(max_length=200, null=False,
verbose_name='Address line 1')
store_address_line_2 = models.CharField(max_length=200, null=False,
verbose_name='Address line 2')
store_city = models.CharField(max_length=200, null=False,
verbose_name='City')
store_state = models.CharField(max_length=200, null=False,
verbose_name='State')
store_zip_code = models.CharField(max_length=200, null=False,
verbose_name='Zip/Pin Code')
store_country = models.CharField(max_length=200, null=False,
verbose_name='Country')
store_phone = models.CharField(max_length=12, verbose_name='Phone')
store_email = models.EmailField(verbose_name='Email')
store_website = models.URLField(verbose_name='Website')
class StoreDepartment(models.Model):
store = models.ForeignKey(Store, verbose_name='Store')
department_name = models.CharField(max_length=200, null=False,
verbose_name='Department name')
department_description = models.TextField(max_length=250, null=False,
verbose_name='Description')
+++++++++
I am using only the dfault Admin provided by django framwork.
I have 2 users, For both users I have created Stores.
But when I try to create StoreDepartment, I see the list of all the stores in the Select box created for "Store" foreign-key field in StoreDepartment model.
How to customize the default form so that user can see only the Stores created by them in the selectbox.
I used the following formfield_for_foreignkey in Model admin and now its working for me. User can see only the stores owned by him.
class StoreDepartmentAdmin(admin.ModelAdmin):
list_display = ['department_name', 'store']
ordering = ['id']
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "store":
kwargs["queryset"] =Store.objects.filter(store_owner=request.user)
return super(StoreDepartmentAdmin,self).formfield_for_foreignkey(db_field, request, **kwargs)