Hello i have this models and i want serialize this en one viewsets
Models.py
class Coche(models.Model):
marca = models.ForeignKey('Marca', null=True, blank=True,verbose_name="Marca")
modelo = models.ForeignKey('Modelo', null=True, blank=True)
version = models.CharField(max_length=120)
estado = models.CharField(max_length=12, choices=Estado_CHOICES)
anio = models.IntegerField ( )
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
def __unicode__(self):
return self.version
def get_absolute_url(self):
return reverse("single_product", kwargs={"pk": self.pk})
class ParteFrontal(models.Model):
coche = models.ForeignKey(Coche, related_name='partefrontal')
imagen = models.ImageField(upload_to='templates/products/images/')
notas = models.TextField(null=True)
I tried as follows
serializers.py
class CocheImagen(serializers.ModelSerializer):
partefrontal = serializers(many=True,read_only=True)
class Meta :
model = Coche
fields = ('marca', 'modelo','version', 'estado','anio','partefrontal')
Viewsets.py
class CocheImagen(viewsets.ModelViewSet):
serializer_class = CocheImagen
queryset = Coche.objects.all()
You need to create another serializer for ParteFrontal like:
class ParteFrontalSerializer(serializers.ModelSerializer):
class Meta:
model = ParteFrontal
fields = ('imagen', 'notas')
Next you can use ParteFrontalSerializer in your CocheImagen serializer like:
class CocheImagen(serializers.ModelSerializer):
partefrontal = ParteFrontalSerializer(many=True,read_only=True)
class Meta :
model = Coche
fields = ('marca', 'modelo','version', 'estado','anio','partefrontal')
Learn more about Nested relationships here
Related
The application has a ticket model:
class Ticket(models.Model):
theme = models.ForeignKey(TicketTheme, on_delete=models.PROTECT)
user = models.ForeignKey(User, related_name='user', on_delete=models.PROTECT)
support = models.ForeignKey(User, on_delete=models.PROTECT)
status = models.ForeignKey(Status, on_delete=models.PROTECT)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
And the message model in the ticket:
class TicketMessage(models.Model):
types = [
('user_msg', 'user_msg'),
('sys_msg', 'sys_msg')
]
ticket = models.ForeignKey(Ticket, on_delete=models.PROTECT)
text = models.CharField(max_length=250, default='')
image = models.ImageField(upload_to='ticket_message_img/', default='')
user = models.ForeignKey(User, on_delete=models.PROTECT)
type = models.CharField(max_length=50, default='user_msg', choices=types)
read = models.IntegerField(max_length=1, default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Serializers:
class TicketSerializer(serializers.ModelSerializer):
user = serializers.SlugRelatedField(
slug_field='username',
read_only=True
)
support = serializers.SlugRelatedField(
slug_field='username',
read_only=True
)
theme = serializers.SlugRelatedField(
slug_field='name',
read_only = True
)
status = serializers.SlugRelatedField(
slug_field='name',
read_only=True
)
class Meta:
model = Ticket
fields = '__all__'
class TicketMessageSerializer(serializers.ModelSerializer):
class Meta:
model = TicketMessage
fields = '__all__'
Urls:
urlpatterns = [
path('api/tickets/', views.TicketSerializerView.as_view()),
path('api/tickets/<int:pk>/all_messages/', views.TicketAllMessagesSerializerView.as_view()),
path('api/tickets/<int:pk>/messages/', views.TicketMessagesSerializerView.as_view()),
]
Controllers:
class TicketSerializerView(generics.ListAPIView):
queryset = Ticket.objects.all()
serializer_class = TicketSerializer
permission_classes = [permissions.IsAuthenticated]
def create(self, validated_data):
return Ticket.objects.create(**validated_data)
class TicketAllMessagesSerializerView(generics.ListAPIView):
queryset = TicketMessage.objects.all()
serializer_class = TicketMessageSerializer
permission_classes = [permissions.IsAuthenticated]
class TicketMessagesPagination(PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 1000
class TicketMessagesSerializerView(generics.ListAPIView):
queryset = TicketMessage.objects.all()
serializer_class = TicketMessageSerializer
pagination_class = TicketMessagesPagination
permission_classes = [permissions.IsAuthenticated]
Questions:
How to filter messages of a specific ticket in the controller (by ticket pk). Now it displays all messages from all tickets.
How to provide access to messages only to the user who created the ticket (the user field), the administrator (superuser) and the manager who took this ticket for processing (the support field)
*if there are comments about the code, it will also be interesting to know
I rewrote controllers, urls and serializers:
urlpatterns = [
path('api/tickets/<int:ticket_id>/messages/',
views.TicketMessageSerializerView.as_view()),
]
class TicketMessageSerializer(serializers.ModelSerializer):
class Meta:
model = TicketMessage
fields = '__all__'
class TicketMessageSerializerView(generics.ListAPIView):
queryset = TicketMessage.objects.all()
serializer_class = TicketMessageSerializer
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
ticket__id=self.kwargs['ticket_id']
)
models.py
class Log(models.Model):
product = models.ForeignKey(ProductInfo,on_delete=models.PROTECT,default=0,verbose_name='کالا')
number = models.IntegerField(null=False,blank=False,default=0,verbose_name='تعداد')
date_to_recived = jmodels.jDateTimeField(verbose_name='تاریخ دریافت محصول')
sender_name = models.CharField(max_length=100,default=None,verbose_name='نام و نام خانوادگی فرستنده')
sender_phone = models.CharField(max_length=30,default=None,verbose_name='شماره تلفن فرستنده')
sender_melli_code = models.CharField(max_length=100, default=None,verbose_name='شماره ملی فرستنده')
sender_sign = models.ImageField(blank=True, null=True, upload_to=image_saving,verbose_name='امضای فرستنده')
reciver_name = models.CharField(max_length=100,default=None,verbose_name='نام و نام خانوادگی گیرنده')
reciver_phone = models.CharField(max_length=30,default=None,verbose_name='شماره تلفن گیرنده')
reciver_melli_code = models.CharField(max_length=100, default=None,verbose_name='شماره ملی گیزنده')
reciver_sign = models.ImageField(blank=True, null=True, upload_to=image_saving,verbose_name='امضای گیرنده')
def __str__(self):
return f'{self.product.title} , number of log = {self.id}'
serializers.py
class LogSerializer(serializers.ModelSerializer):
class Meta:
model = Log
fields = '__all__'
views.py
class LogViewSet(viewsets.ModelViewSet):
queryset = Log.objects.all().order_by('-id')
serializer_class = LogSerializer
permission_classes = [IsAdminUser]
filter_backends = (filters.SearchFilter,)
search_fields = ['product__title','product__owner__username','reciver_name',
'sender_name']
def retrieve(self, request, pk=None):
obj = get_object_or_404(self.queryset, pk=pk)
serializer_class = LogSerializer(obj)
return Response(serializer_class.data)
def update(self, request, pk):
obj = Log.objects.get(pk=pk)
serializer = LogSerializer(obj, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
i'll be thankfull if you help me.
this is my imagefield when i wanna update my data.
and my imageFields and datefields are blank.
i want to assign logged in user to the model but perform_create not working
any help how to fix this.
OkHttp: {"aggregator":["Invalid pk "0" - object does not exist."]}
class FarmerViewset(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
# mixins.DestroyModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet
):
queryset = Farmer.objects.all()
serializer_class = FarmerSerializers
def perform_create(self, serializer):
serializer.validated_data['aggregator'] = self.request.user
serializer.save()
seliarizer.py
class FarmerSerializers(serializers.ModelSerializer):
farmer_requests = RequestSerializers(many=True, read_only=True)
class Meta:
model = Farmer
fields = '__all__'
extra_kwargs = {
'created_at': {'read_only': True},
'updated_at': {'read_only': True},
}
model
class Farmer(models.Model):
first_name = models.CharField(_(" Enter first name"),max_length=30)
last_name = models.CharField(_(" Enter last name"),max_length=30)
phone = models.IntegerField(_("Telephone number"), null=True)
district = models.ForeignKey(
"authentication.District",
verbose_name=("district"),
on_delete = models.CASCADE
)
sector = models.ForeignKey(
"authentication.Sector",
verbose_name=("sector"),
on_delete = models.CASCADE
)
aggregator = models.ForeignKey(
"authentication.User",
verbose_name=("aggregator"),
on_delete = models.CASCADE
)
created_at = models.DateTimeField(_("Date of creation"),default=timezone.now)
updated_at = models.DateTimeField(_("Updated date"),default=timezone.now)
Did you use permission_classes = (IsAuthenticated,) in your views.py (at FarmerViewset). And also did you add to settings.py the following line ?
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}`
I have three model. Product, ShoppingCart and CartDetails. when i add a product to cart i want to save data in ShoppingCart and CartDetails.ShoppingCart (id) is related with CartDetails (cart_id).And CartDetails (product_id) is related with Product(id). Now when i am posting data it shows the error "Column 'product_id' cannot be null". I think i am missing a silly thing. But cannot find out the silly thing. I am new to django rest framework.I am using angular for front end. I don't understand what i am doing wrong.Thanks in advance.
models.py
class Product(models.Model):
product_name = models.CharField(max_length=200)
cat_id = models.ForeignKey('Category', on_delete=models.CASCADE, db_column='cat_id')
description = models.TextField()
image_url = models.ImageField(upload_to='images/product_name/%Y/%m/%d/')
sell_price = models.IntegerField()
cost_price = models.IntegerField()
discount_price = models.IntegerField()
active = models.BooleanField()
create_date = models.DateTimeField(default=datetime.now)
def __str__(self):
return self.product_name
class Meta:
db_table = "products"
class ShoppingCart(models.Model):
create_date = models.DateTimeField(default=datetime.now)
amount = models.IntegerField(default=0)
def __int__(self):
return self.id
class Meta:
db_table = "shopping-cart"
class CartDetails(models.Model):
cart = models.ForeignKey(ShoppingCart, related_name='cart_details', on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
qty = models.IntegerField(default=0)
amount = models.IntegerField(default=0)
create_date = models.DateTimeField(default=datetime.now)
def __int__(self):
return self.id
class Meta:
db_table = "cart-details"
serializers.py
class ProductSerializer(serializers.ModelSerializer):
image_url = Base64ImageField(max_length=None, use_url=True)
class Meta:
model = Product
fields = ('id', 'product_name', 'description', 'image_url', 'sell_price', 'cost_price',
'discount_price', 'active', 'cat_id')
class CartDetailSerializer(serializers.ModelSerializer):
class Meta:
model = CartDetails
fields = ('product', 'qty', 'amount')
class ShoppingCartSerializer(serializers.ModelSerializer):
cart_details = CartDetailSerializer()
class Meta:
model = ShoppingCart
fields = ('id', 'amount', 'cart_details')
def create(self, validated_data):
carts_data = validated_data.pop('cart_details')
# cart = ShoppingCart.objects.create(**validated_data)
# for data in carts_data:
# CartDetails.objects.create(cart=cart, **carts_data)
return validated_data
views.py
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
class ShoppingCartViewSet(viewsets.ModelViewSet):
queryset = ShoppingCart.objects.all()
serializer_class = ShoppingCartSerializer
class CartDetailsViewSet(viewsets.ModelViewSet):
queryset = CartDetails.objects.all()
serializer_class = CartDetailSerializer
This is angular service to post data
private create(product) {
const cart = {
amount: product.sell_price,
cart_details: {
qty: 1,
product: product.id,
amount: product.sell_price
}
};
return this.http.post(this.globalService.baseUrl + 'shopping-cart/', cart);
}
If i am not wrong, problem is here
product_id = ProductSerializer(read_only=True, source='product.id')
as you make this as read_only field, so product_id is not writing on instance creation. read_only should be removed.
product_id = ProductSerializer(source='product.id')
In serializer:
class EventUserRegisterSerializer(ModelSerializer):
first_name = serializers.CharField(write_only=True)
last_name = serializers.CharField(write_only=True)
email = serializers.EmailField(validators=
[UniqueValidator(queryset=User.objects.all())], write_only=True)
views:
try:
user = User.objects.get(phone_number=phone_number,
email=email)
user.first_name = first_name
user.last_name = last_name
except User.DoesNotExist:
user =
User.objects.create(username=username,first_name=first_name,
last_name=last_name, phone_number=phone_number,
email=email)
model:
class User(AbstractUser):
first_name = models.CharField(max_length=200, blank=True,
default="")
last_name = models.CharField(max_length=200, blank=True,
default="")
phone_number = models.CharField(max_length=20, unique=True,
default="")
timestamp = UnixDateTimeField(auto_now=True)
#property
def unique_id(self):
return self.first_name + self.timestamp
I have a partial payment system so i have to done multiple 'post' ,but validation error occurs