How do i call a primary key from another view in another form in django? - django-models

I have a stocks model that relies on GRN (Goods Receiving Note) model primary key in order to store stocks of a certain GRN in the database. I would like to humbly ask for guidance on how i can click a GRN and enter stocks in a form with the open GRN No already selected in this form.
Below are my views:
def grns(request):
grns = GRN.objects.all()
return render (request, 'products/GRNS.html', {'grns' : grns})
def grn(request, pk):
gnrObj = GRN.objects.get(GRN_id = pk)
return render(request, 'products/stocks_in.html', {'grn': gnrObj})
def createGrn(request):
form = GrnForm()
if request.method == 'POST':
form = GrnForm(request.POST)
if form.is_valid():
form.save()
return redirect('grns')
context = {'form': form}
return render (request, 'products/grn_form.html', context)
def stocks(request):
stocks = Stock.objects.all()
return render (request, 'products/stocks_in.html', {'stocks' : stocks})
def stock(request, pk):
stockObj = stock.objects.get(GRN_id = pk)
return render(request, 'products/stocks_in_form.html', {'stock': stockObj})
def createStock(request):
form = StockForm()
if request.method == 'POST':
form = StockForm(request.POST)
if form.is_valid():
form.save()
return redirect('stocks')
context = {'form': form}
return render (request, 'products/stocks_in_form.html', context)
Below are my urls:
#GRNS Urls
path('grns', views.grns, name = "grns"),
path('create-grn/', views.createGrn, name = "create-grn"),
path('grn/<str:pk>/', views.grn, name = "grn"),
#Stocks Urls
path('stocks', views.stocks, name = "stocks"),
path('create-stock/', views.createStock, name = "create-stock"),
path('stock/<str:pk>/', views.stock, name = "stock"),
Below are my forms:
class GrnForm(ModelForm):
class Meta:
model = GRN
fields = ['GRN_no', 'date', 'supplier']
def __init__(self, *args, **kwargs):
super(GrnForm, self).__init__(*args, **kwargs)
self.fields['GRN_no'].widget.attrs.update(
{'class': 'form-control'}
)
self.fields['date'].widget.attrs.update(
{'class': 'form-control', 'type': 'date'}
)
self.fields['supplier'].widget.attrs.update(
{'class': 'form-control'}
)
class StockForm(ModelForm):
class Meta:
model = Stock
fields = ['GRN', 'product', 'warehouse', 'unit_price', 'quantity']
def __init__(self, *args, **kwargs):
super(StockForm, self).__init__(*args, **kwargs)
self.fields['GRN'].widget.attrs.update(
{'class': 'form-control', 'value':'grn.GRN_id'}
)
self.fields['product'].widget.attrs.update(
{'class': 'form-control'}
)
self.fields['warehouse'].widget.attrs.update(
{'class': 'form-control'}
)
self.fields['unit_price'].widget.attrs.update(
{'class': 'form-control'}
)
self.fields['quantity'].widget.attrs.update(
{'class': 'form-control'}
)

Related

I have used djangorest to create an api but when i make a post request it returns an error saying 400 BAD request

model :
class Post(models.Model):
author = models.ForeignKey(get_user_model(), related_name="posts", on_delete=models.CASCADE, unique=False)
title = models.CharField(max_length=300)
text = models.TextField(blank=True)
creationDate = models.DateTimeField(default=timezone.now())
publicationDate = models.DateTimeField(blank=True, null=True)
def publish(self):
self.publicationDate = timezone.now()
self.save()
def __str__(self):
return self.title
this is the serializer :
class PostSerializer(serializers.ModelSerializer):
def create(self, validated_data):
post = Post.objects.create(
author=validated_data["author"], title=validated_data["title"], text=validated_data["text"]
)
post.save()
return post
class Meta:
model = Post
fields = ["author", "title", "text", "pk", 'publicationDate']
this is the api view :
class PostList(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = Post.objects.all()
serializer_class = PostSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
and this is the request I`m making :
axios.post('/api/posts/', form, {
"headers": {
'Content-Type': 'application/json',
}
})
.then(response => console.log(response.data))
this is the error it returns
"POST http://127.0.0.1:8000/api/posts/ 400 (Bad Request)"
I have been at this problem for days now and i have tried everything but it just wont work

Update Successfully but Data not update in db. Django rest framework

I'm working on my final year project, and I need some help to understand what is actually happening, The problem is that: I hit the Update request through postman which gives the successful message for updating the data. but when I check my Database there is no updated data. I also did the debugging but there was no exception by which I can understand the problem Anyone can please help me?
I'm using
PgAdmin for my database.
Django==4.0.2
djangorestframework==3.13.1
djangorestframework-jwt==1.11.0
djangorestframework-simplejwt==5.0.0
psycopg2==2.9.3**.
My Models:
class Company(Base):
company_name = models.CharField(max_length=255, db_column='Company_Name')
company_email = models.EmailField(unique=True, max_length=255, db_column='company_email')
company_manager_name = models.CharField(max_length=255, db_column='Manager_Name')
company_address = models.CharField(max_length=255, db_column='Company_address')
about_company = models.TextField()
company_website = models.URLField(max_length=200)
is_active = models.BooleanField(default=True, db_column='IsActive', help_text='I will use this for enable/disable '
'a specific record')
class Meta:
db_table: 'Company'
def __str__(self):
return self.company_name
def save(self, *args, **kwargs):
try:
if not self.pk:
self.company_email = self.company_email.replace(" ", "").lower()
super().save()
except Exception:
raise
class Base(models.Model):
"""Following fields are abstract and will be use in All over the project Any time Anywhere"""
create_by = models.BigIntegerField(db_column='CreatedBy', null=True, blank=True, default=0)
create_on = models.DateTimeField(db_column='CreatedOn', auto_now_add=True)
modified_by = models.BigIntegerField(db_column='ModifiedBy', null=True, blank=True, default=0)
modified_on = models.DateTimeField(db_column='ModifiedOn', auto_now=True)
deleted_by = models.BigIntegerField(db_column='DeletedBy', null=True, blank=True, default=0)
deleted_on = models.DateTimeField(db_column='DeletedOn', auto_now=True)
status = models.BigIntegerField(db_column='Status', default=0, help_text='I will use this field for making'
'the status like pending approved and '
'for some other purpose by Default it is '
'Zero which has no meaning', )
class Meta:
abstract: True
serializer.py:
class CompanyUpdateSerializer(serializers.ModelSerializer):
company_name = serializers.CharField(required=True, allow_null=False, allow_blank=False)
company_email = serializers.CharField(required=True, allow_null=False, allow_blank=False)
company_manager_name = serializers.CharField(required=True, allow_null=False, allow_blank=False)
company_address = serializers.CharField(required=True, allow_null=False, allow_blank=False)
about_company = serializers.CharField(required=True, allow_null=False, allow_blank=False)
company_website = serializers.URLField(allow_blank=False, allow_null=False)
class Meta:
model = Company
fields = ['id', 'company_name', 'company_email', 'company_manager_name', 'company_address', 'about_company',
'company_website']
def update(self, instance, validated_data):
try:
instance.company_name = validated_data.get('company_name', instance.company_name)
instance.company_email = validated_data.get('company_email', instance.company_email)
instance.company_manager_name = validated_data.get('company_manager_name', instance.company_manager_name)
instance.company_address = validated_data.get('company_address', instance.company_address)
instance.about_company = validated_data.get('about_company', instance.about_company)
instance.company_website = validated_data.get('company_website', instance.company_website)
instance.save()
return instance
except Exception as e:
raise e
Views.py
def put(self, request, pk=None):
try:
id1 = pk
saved_company = Company.objects.get(pk=id1)
data = request.data
serializer = CompanyUpdateSerializer(instance=saved_company, data=data)
if serializer.is_valid():
serializer.save()
return self.send_response(success=True, code=f'200', status_code=status.HTTP_200_OK,
description='Company is updated')
return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
description=serializer.errors)
except ObjectDoesNotExist:
return self.send_response(code='422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
description="No Company matches the given query.")
except IntegrityError:
return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
description="Email Already Exist")
except Company.DoesNotExist:
return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
description="Company Model doesn't exists")
except FieldError:
return self.send_response(code=f'500', description="Cannot resolve keyword given in 'order_by' into field")
except Exception as e:
return self.send_response(code=f'500', description=e)
The problem comes from Company.save() method.
You overrode it as
class Company(Base):
...
def save(self, *args, **kwargs):
try:
if not self.pk:
self.company_email = self.company_email.replace(" ", "").lower()
super().save()
except Exception:
raise
Notice the call of super().save() inside the self.pk is None if statement block.
This will make the actual save method to be called only when the pk is None, meaning that only when a new instance is created, not when an instance is updated.
Moving the super().save() call to be outside the if statement should handle both creating and updating.
class Company(Base):
...
def save(self, *args, **kwargs):
try:
if not self.pk:
self.company_email = self.company_email.replace(" ", "").lower()
super().save(*args, **kwargs)
except Exception:
raise

__str__ returned non-string (type Category). when I add post from admin

After I added user and date_added in the Photo models, when I add post from admin its throws me an error saying: str returned non-string (type Category), when I click on the addpost link in the home template its throw another error: 'tuple' object has no attribute 'name'. how can I solve that ?
the models.py:
from django.db import models
from cloudinary.models import CloudinaryField
from django.contrib.auth.models import User
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=100, null=False, blank=False)
def __str__(self):
return self.name
class Photo(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True,
blank=True)
image = CloudinaryField('image')
description = models.TextField(null=True)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.category
the view.py file:
def home(request):
category = request.GET.get('category')
if category == None:
photos = Photo.objects.all()
else:
photos = Photo.objects.filter(category__name=category)
categories = Category.objects.all()
context = {'categories': categories, 'photos': photos}
return render(request, 'home.html', {'categories': categories, 'photos': photos} )
def viewPhoto(request, pk):
photo = Photo.objects.get(id=pk)
return render(request, 'photo.html', {'phpto': photo})
class PostCreativeView(LoginRequiredMixin, CreateView):
model = Photo, Category
fields = ['description', 'image', 'category', 'name']
template_name = 'post_create.html'
def form_valid(self, form):
form.instance.user = self.request.user
return super (PostCreativeView, self).form_valid(form)
Well it has to do with your category name and model you added into post create view.py and so you
have do something like this:
views.py
class PostCreativeView(LoginRequiredMixin, CreateView):
model = Photo
fields = ['description', 'image', 'category']
template_name = 'post_create.html'
def form_valid(self, form):
form.instance.user = self.request.user
return super (PostCreativeView, self).form_valid(form)
#.......
# Models.py
class Photo(models.Model):
#>>>...
def __str__(self):
return str(self.category)
You should return the str(…) of the category, so:
class Photo(models.Model):
# …
def __str__(self):
return str(self.category)

How to make use of filter using ContentType to check if model instance is already present or not

I am trying to implement like functionality based on this . I want to restrict user to hit like on a event only once. But I am getting the following error. I have added full error details at bottom
Exception Type: AttributeError at /api/event/likes/create/
Exception Value: 'str' object has no attribute '_meta'
models.py
class ThumbsUpManager(models.Manager):
def create_by_model_type(self, model_type, slug, content, user, parent_obj=None):
model_qs = ContentType.objects.filter(model=model_type)
if model_qs.exists():
some_model = model_qs.first().model_class()
obj_qs = some_model.objects.filter(slug=slug)
if obj_qs.exists() and obj_qs.count() == 1:
instance = self.model()
instance.content = content
instance.user = user
instance.content_type = model_qs.first()
instance.object_id = obj_qs.first().id
if parent_obj:
instance.parent = parent_obj
instance.save()
return instance
return None
class Thumbsup(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
parent = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE)
content = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=True)
objects = ThumbsUpManager()
class Meta:
ordering = ['-timestamp']
def __str__(self):
return str(self.user.username)
#property
def is_parent(self):
if self.parent is not None:
return False
return True
urls.py
urlpatterns = [
path('create/', ThumbsUpCreateAPIView.as_view(), name='create'),
]
view.py
class ThumbsUpCreateAPIView(CreateAPIView):
queryset = Thumbsup.objects.all()
permission_classes = [IsAuthenticated, ]
def get_serializer_class(self):
model_type = self.request.GET.get("type")
slug = self.request.GET.get("slug")
obj_qs = Thumbsup.objects.all()
print(obj_qs)
parent_id = self.request.GET.get("parent_id", None)
return create_thumbs_up_serializer(
model_type=model_type,
slug=slug,
parent_id=parent_id,
user=self.request.user
)
serializers.py
def create_thumbs_up_serializer(model_type=None, slug=None, parent_id=None, user=None):
class ThumbsUpCreateSerializer(ModelSerializer):
class Meta:
model = Thumbsup
fields = [
'id',
'content',
'timestamp',
]
def __init__(self, *args, **kwargs):
self.model_type = model_type
self.slug = slug
self.parent_obj = None
self.user = user
if parent_id:
parent_qs = Thumbsup.objects.filter(id=parent_id)
if parent_qs.exists() and parent_qs.count() == 1:
self.parent_obj = parent_qs.first()
return super(ThumbsUpCreateSerializer, self).__init__(*args, **kwargs)
def validate(self, data):
model_type = self.model_type
slug = self.slug
model_qs = ContentType.objects.filter(model=model_type)
if not model_qs.exists() or model_qs.count() != 1:
raise ValidationError("This is not a valid content type")
SomeModel = model_qs.first().model_class()
obj_qs = SomeModel.objects.filter(slug=self.slug)
if not obj_qs.exists() or obj_qs.count() != 1:
raise ValidationError("This is not a slug for this content type")
######################### ######################### #########################
How do I need to make query here to check if the user already liked the Event or not?
I tried the following way, but it is not working.
user_act = Thumbsup.objects.filter(user=self.user, content_type=ContentType.objects.get_for_model(model_type))
if user_act.exists():
raise ValidationError("You have already liked the event")
return data
def create(self, validated_data):
content = validated_data.get("content")
if user:
main_user = user
else:
main_user = User.objects.all().first()
model_type = self.model_type
slug = self.slug
parent_obj = self.parent_obj
thumbsup = Thumbsup.objects.create_by_model_type(
model_type, slug, content, main_user,
parent_obj=parent_obj,
)
return thumbsup
return ThumbsUpCreateSerializer
Traceback:
File "E:\GIT\blog\backend\venv\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\core\handlers\base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\core\handlers\base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\views\decorators\csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\views\generic\base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\views.py" in dispatch
497. response = self.handle_exception(exc)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\views.py" in handle_exception
457. self.raise_uncaught_exception(exc)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\views.py" in raise_uncaught_exception
468. raise exc
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\views.py" in dispatch
494. response = handler(request, *args, **kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\generics.py" in post
190. return self.create(request, *args, **kwargs)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\mixins.py" in create
18. serializer.is_valid(raise_exception=True)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\serializers.py" in is_valid
235. self._validated_data = self.run_validation(self.initial_data)
File "E:\GIT\blog\backend\venv\lib\site-packages\rest_framework\serializers.py" in run_validation
433. value = self.validate(value)
File "E:\GIT\test-heroku4\thumbsup\api\serializers.py" in validate
124. user_act = Thumbsup.objects.filter(user=self.user, content_type=ContentType.objects.get_for_model(model_type))
File "E:\GIT\blog\backend\venv\lib\site-packages\django\contrib\contenttypes\models.py" in get_for_model
40. opts = self._get_opts(model, for_concrete_model)
File "E:\GIT\blog\backend\venv\lib\site-packages\django\contrib\contenttypes\models.py" in _get_opts
27. model = model._meta.concrete_model
Exception Type: AttributeError at /api/event/likes/create/
Exception Value: 'str' object has no attribute '_meta'
I checked the model instance before saving in model manager like below and it is working fine. I do not know whether this is the correct way to do the task or not (I'm very new to django. Suggestions are most welcome)
def create_by_model_type(self, model_type, slug, content, user, parent_obj=None):
model_qs = ContentType.objects.filter(model=model_type)
if model_qs.exists():
some_model = model_qs.first().model_class()
obj_qs = some_model.objects.filter(slug=slug)
if obj_qs.exists() and obj_qs.count() == 1:
instance = self.model()
instance.content = content
instance.user = user
instance.content_type = model_qs.first()
instance.object_id = obj_qs.first().id
if parent_obj:
instance.parent = parent_obj
#### Here I have checked for existence before saving the instance ####
if Thumbsup.objects.filter(object_id=instance.object_id, user=instance.user).exists():
raise ValidationError({'already_liked': 'You have already liked the item'})
instance.save()
return instance
return None

How to add custom user field (phone_number) in django default user table?

I need to add a custom field called phone_number to the default django user table
Everything work fine but the phone_number field and value does not save in Table Django User.
Here is my custom form code
class SignUpForm(UserCreationForm):
username = forms.EmailField(label="Email Address", max_length=254, help_text='Required a valid email address.')
phone_number = forms.CharField(max_length=30, help_text='Required.')
class Meta:
model = User
fields = ('first_name', 'last_name', 'username', 'phone_number', 'password1', 'password2')
Here is my view code for user registration
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
mail_subject = 'Activate Your Account.'
message = render_to_string('app/account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token': account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('username')
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
return render(request, 'app/account_confirm_message.html')
else:
form = SignUpForm()
return render(request, 'app/signup.html', {'form': form})
My Model is here
class Profile(models.Model):
STUDENT = 1
TEACHER = 2
ROLE_CHOICES = (
(STUDENT, 'Student'),
(TEACHER, 'Teacher'),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
email_confirmed = models.BooleanField(default=False)
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
# this method called for admin panel
class Meta:
verbose_name = 'profile'
verbose_name_plural = 'profiles'
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()

Resources