Filtering issue in DRF - python

The problem I'm having looks like:
TypeError: init() got an unexpected keyword argument 'name'
"GET /apartmentimages/ HTTP/1.1" 500 136691
I have such a model.py class:
class Apartment(models.Model):
apartment_title = models.CharField(max_length=200)
apartment_description = models.TextField()
apartment_location = models.CharField(max_length=200)
apartment_people_quantity = models.PositiveIntegerField()
apartment_price = models.CharField(max_length=200)
apartment_type = models.CharField(max_length=50, null=True)
def __str__(self):
return self.apartment_title
class ApartmentImage(models.Model):
apartment = models.ForeignKey(Apartment, on_delete=models.CASCADE)
image = models.ImageField(upload_to='images/', null=True, blank=True)
And serializers.py class:
class ApartmentSerializer(serializers.ModelSerializer):
class Meta:
model = Apartment
fields = (
'id',
'url',
'apartment_title',
'apartment_description',
'apartment_location',
'apartment_people_quantity',
'apartment_price',
'apartment_type',
)
class ApartmentImageSerializer(serializers.ModelSerializer):
class Meta:
model = ApartmentImage
fields = ('id', 'url', 'apartment', 'image',)
in views.py:
apartment_id = django_filters.CharFilter(name="apartment__id",
queryset=Apartment.objects.all())
class Meta:
model = ApartmentImage
fields = ('apartment_id',)
class ApartmentImageView(viewsets.ModelViewSet):
queryset = ApartmentImage.objects.all()
serializer_class = ApartmentImageSerializer
filter_backends = (DjangoFilterBackend,)
filter_class = ApartmentImageFilter

You have no name as an attribute in django-filters. Maybe what are you looking for is field_name and neither do you need queryset=Apartment.objects.all(). If you are looking for a field that is field_name then your CharFielter should look like this apartment_id = django_filters.CharFilter(field_name="apartment__id", lookup_expr='iexact') and maybe if you haven't overwritten the id generation it should probably be a NumberFilter() if I am not wrong.

Related

How to access model's verbose name in a serializer?

I want to access verbose name of models to put it as a key in serializer. But I can't find a way to do it.
My models are:
class ProductCategory(models.Model):
name = models.CharField(max_length=150, unique=True)
created_at = models.DateTimeField(default=timezone.now)
modified_at = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.name
class DeviceTypeCategory(ProductCategory):
product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE,
related_name="device_types")
class Meta:
verbose_name = _("Device type")
verbose_name_plural = _("Device types")
class DeviceBrandCategory(ProductCategory):
product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE,
related_name="device_brands")
class PartTypeCategory(ProductCategory):
product_category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE, related_name="part_types")
And my serializer:
class ProductCategorySerializer(serializers.ModelSerializer):
device_types = serializers.StringRelatedField(many=True)
device_brands = serializers.StringRelatedField(many=True)
part_types = serializers.StringRelatedField(many=True)
class Meta:
model = ProductCategory
fields = ('name', 'device_types', 'device_brands', 'part_types')
Any suggestions would help. I would also be glad to hear out other ideas on how to create categories model. I've tried django-mptt, but I need product to belong to multiple subcategories. The django-polymorphic-mptt could have help. But I couldn't find proper documentation.
You can do something like the following:
class ProductCategorySerializer(serializers.ModelSerializer):
device_types = serializers.StringRelatedField(many=True)
device_brands = serializers.StringRelatedField(many=True)
part_types = serializers.StringRelatedField(many=True)
plural_name = serializers.SerializerMethodField()
def get_plural_name(self, obj):
return ProductCategory._meta.verbose_name_plural
class Meta:
model = ProductCategory
fields = ('name', 'device_types', 'device_brands', 'part_types', 'plural_name')

Django returning chain of 2 different model querysets

Here is my view
serializer_class = SceneSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
scene = Scene.objects.filter(user = self.request.user)
for s in scene:
test = Scene.objects.get(static_id = s.static_id)
lights = test.light.all()
temp = list(chain(scene, lights))
Here are my 2 serializers
class LightSerializer(serializers.ModelSerializer):
class Meta:
model = Light
fields = '__all__'
class SceneSerializer(serializers.ModelSerializer):
class Meta:
model = Scene
fields = '__all__'
Here is my models
class Light(models.Model):
static_id = models.AutoField(primary_key=True)
id = models.CharField(max_length=100, blank=True, null=True)
company = models.CharField(max_length=25, blank=True, null=True)
name = models.CharField(max_length=100, blank=True, null=True)
label = models.CharField(max_length=100, blank=True, null=True)
user = models.ForeignKey(User,on_delete=models.DO_NOTHING, related_name='userLights' )
def __str__(self):
return "{0} - {1}".format(self.user,self.static_id)
class Scene(models.Model):
static_id = models.AutoField(primary_key=True)
color = RGBColorField()
title = models.CharField(max_length=100, blank=True, null=True)
user = models.ForeignKey(User,on_delete=models.DO_NOTHING, related_name='userScenes' )
light = models.ManyToManyField(Light)
def __str__(self):
return "{0} - {1}".format(self.user,self.static_id)
Goal is to return the complete objects of the scene and the lights attached to each scene. the chain is working correctly but when I return the chain I am getting
You can include reverse relationships in serializers by adding the reverse relationship to fields
class SceneSerializer(serializers.ModelSerializer):
class Meta:
model = Scene
fields = ['light', 'static_id', 'color', 'title', 'user']
This will just return a list of ids, to serialize the related objects you can add the related serializer with many=True
class SceneSerializer(serializers.ModelSerializer):
light = LightSerializer(many=True)
class Meta:
model = Scene
fields = ['light', 'static_id', 'color', 'title', 'user']

How to save three related models in one DRF endpoint?

I have 4 related models and I need to implement the functionality to consistently create instances of these models in a database in one post query. For this I use override of the APIView class post method.
models
class VendorContacts(models.Model):
contact_id = models.AutoField(primary_key=True)
vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE)
contact_name = models.CharField(max_length=45, blank=True)
phone = models.CharField(max_length=45, blank=True)
email = models.CharField(max_length=80, blank=True, unique=True)
class Meta:
db_table = 'vendor_contacts'
class VendorModuleNames(models.Model):
vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE, primary_key=True)
module = models.ForeignKey(Modules, models.DO_NOTHING)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'vendor_module_names'
unique_together = (('vendor', 'module'),)
class Vendors(models.Model):
COUNTRY_CHOICES = tuple(COUNTRIES)
vendorid = models.AutoField(primary_key=True)
vendor_name = models.CharField(max_length=45, unique=True)
country = models.CharField(max_length=45, choices=COUNTRY_CHOICES)
nda = models.DateField(blank=True, null=True)
user_id = models.ForeignKey('c_users.CustomUser', on_delete=models.PROTECT)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'vendors'
unique_together = (('vendorid', 'timestamp'),)
class Modules(models.Model):
MODULES_NAME =tuple(MODULES)
mid = models.AutoField(primary_key=True)
module_name = models.CharField(max_length=50, choices=MODULES_NAME)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'modules'
unique_together = (('mid', 'timestamp'),)
serializer.py
class VendorsSerializer(serializers.ModelSerializer):
class Meta:
model = Vendors
fields = ('vendor_name',
'country',
'nda',)
class VendorContactSerializer(serializers.ModelSerializer):
class Meta:
model = VendorContacts
fields = (
'contact_name',
'phone',
'email',)
class VendorModulSerializer(serializers.ModelSerializer):
class Meta:
model = VendorModuleNames
fields = ('module',)
class ModulesSerializer(serializers.ModelSerializer):
class Meta:
model = Modules
fields = ('module_name', )
views.py
class VendorsCreateView(APIView):
"""Create new vendor instances from form"""
def post(self, request, *args, **kwargs):
vendor_serializer = VendorsSerializer(data=request.data)
vendor_contact_serializer = VendorContactSerializer(data=request.data)
vendor_modules_serializer = VendorModulSerializer(data=request.data)
module_serializer = ModulesSerializer(data=request.data)
try:
vendor_serializer.is_valid(raise_exception=True) \
and vendor_contact_serializer.is_valid(raise_exception=True) \
and vendor_modules_serializer.is_valid(raise_exception=True) \
and module_serializer.is_valid(raise_exception=True)
vendor_serializer.save(user_id=request.user)
# ....
# Some new logic here ????
# ...
except ValidationError:
return Response({"errors": (vendor_serializer.errors,
vendor_contact_serializer.errors,
vendor_modules_serializer.errors
)},
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(request.data, status=status.HTTP_200_OK)
There is no problem saving one Vendor model, but I can't imagine how to save cascading all related models in a single request.
save returns the newly saved object, which you can then pass into the subsequent save() methods:
vendor = vendor_serializer.save(user_id=request.user)
module = module_serializer.save()
vendor_module = vendor_modules_serializer.save(module=module, vendor=vendor)
vendor_contact = vendor_contact_serializer.save(vendor=vendor)

Django-rest-framework drf-extensions: Nested routers/urls are not filtering

I can't get the my Router to filter my requests based on the "parents_query_lookup".
Here's my code:
urls.py:
from rest_framework_extensions.routers import ExtendedSimpleRouter
from .views import OrganizationViewSet, GroupViewSet, BootGroupViewSet
router = ExtendedSimpleRouter()
(router.register(r'organizations', OrganizationViewSet,
base_name='organization')
.register(r'groups', GroupViewSet, base_name='organizations-group',
parents_query_lookups=['resource__organization'])
.register(r'boot_groups', BootGroupViewSet,
base_name='organizations-groups-boot_group',
parents_query_lookups=['group__resource__organization', 'group']))
urlpatterns = router.urls
views.py:
from rest_framework.viewsets import ModelViewSet
from rest_framework_extensions.mixins import NestedViewSetMixin
from .models import Organization, OrganizationSerializer, \
Group, GroupSerializer, BootGroup, BootGroupSerializer
class OrganizationViewSet(NestedViewSetMixin, ModelViewSet):
queryset = Organization.objects.all()
serializer_class = OrganizationSerializer
class GroupViewSet(NestedViewSetMixin, ModelViewSet):
queryset = Group.objects.all()
serializer_class = GroupSerializer
class BootGroupViewSet(NestedViewSetMixin, ModelViewSet):
queryset = BootGroup.objects.all()
serializer_class = BootGroupSerializer
enums.py:
class ResourceTypeEnum:
RESOURCE_TYPE_GROUP = 'group'
RESOURCE_TYPE_VM = 'vm'
RESOURCE_TYPE_CHOICES = (
(RESOURCE_TYPE_GROUP, RESOURCE_TYPE_GROUP),
(RESOURCE_TYPE_VM, RESOURCE_TYPE_VM)
)
models.py:
from django.db.models import Model
from rest_framework.serializers import ModelSerializer
from .enums import ResourceTypeEnum
class Organization(Model):
organization_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
parent = models.ForeignKey('self', blank=True, null=True)
class Meta:
unique_together = (("name", "parent"))
verbose_name = "Organization"
verbose_name_plural = "Organizations"
app_label = 'api_manager'
db_table = 'organization'
def __unicode__(self):
return self.name
class OrganizationSerializer(ModelSerializer):
class Meta:
model = Organization
fields = ('name', 'parent')
depth = 2
class Resource(Model):
resource_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=55)
type = models.CharField(
max_length=5, choices=ResourceTypeEnum.RESOURCE_TYPE_CHOICES)
organization = models.ForeignKey(Organization)
class Meta:
verbose_name = "Resource"
verbose_name_plural = "Resources"
app_label = 'api_manager'
db_table = 'resource'
def __unicode__(self):
return self.name
class ResourceSerializer(ModelSerializer):
class Meta:
model = Resource
fields = ('name', 'type', 'organization')
depth = 2
class Group(Model):
resource = models.OneToOneField(Resource, primary_key=True)
is_consistent = models.BooleanField()
parent = models.ForeignKey('self', blank=True, null=True)
class Meta:
verbose_name = "Group"
verbose_name_plural = "Groups"
app_label = 'api_manager'
db_table = 'group'
def __unicode__(self):
return "%s: %s" % (self.resource.organization, self.resource)
class GroupSerializer(ModelSerializer):
class Meta:
model = Group
fields = ('resource', 'is_consistent', 'parent')
depth = 2
class BootGroup(Model):
boot_group_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
boot_order = models.PositiveSmallIntegerField(default=1)
group = models.ForeignKey(Group)
class Meta:
unique_together = (("boot_order", "group"))
verbose_name = "BootGroup"
verbose_name_plural = "BootGroups"
app_label = 'api_manager'
db_table = 'boot_group'
def __unicode__(self):
return "%s: %s" % (self.group.resource, self.name)
class BootGroupSerializer(ModelSerializer):
class Meta:
model = BootGroup
fields = ('name', 'boot_order', 'group')
depth = 2
class Vm(Model):
resource = models.OneToOneField(Resource, primary_key=True)
hostname = models.CharField(max_length=200, blank=True, null=True)
group = models.ForeignKey(Group, blank=True, null=True)
boot_group = models.ForeignKey(BootGroup, blank=True, null=True)
class Meta:
verbose_name = "Vm"
verbose_name_plural = "Vms"
app_label = 'api_manager'
db_table = 'vm'
def __unicode__(self):
return "%s: %s" % (self.resource.organization, self.resource)
class VmSerializer(ModelSerializer):
class Meta:
model = Vm
fields = ('resource', 'hostname', 'group', 'boot_group')
depth = 2
No matter what I try, something like "organizations/1/groups" returns all of the Group models, regardless of Organization. Am I missing something? Thanks in advance for the help.
Based on yours router definition, you need to define a queryset in GroupViewSet
from rest_framework_extensions.utils import compose_parent_pk_kwarg_name
def get_queryset(self):
resource_id = self.kwargs.get(compose_parent_pk_kwarg_name('resource_organization')
return Group.objects.filter(resource=resource_id)
The filter value can be find in kwargs as parent_lookup_<parents_query_lookups> or you can retrieve the parent query dict with self.get_parents_query_dict()

Django NOT NULL constraint failed: shop_product.user_id

I am new to Django and I am trying to learn by practicing with some project but I am stuck with this problem,
NOT NULL constraint failed: shop_product.user_id
models.py
from django.db import models
from django.conf import settings
from django.core.urlresolvers import reverse
class Category(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='category_created')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=True)
class Meta:
ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
class Product(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='product_created')
category = models.ForeignKey(Category, related_name='products')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True)
image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField()
available = models.BooleanField(default=True)
negiotiable = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='product_liked',
blank=True)
class Meta:
ordering = ('name',)
index_together = (('id', 'slug'),)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('products_detail',
args=[self.slug])
Here is my views.py but am not sure if there is problem with my views and I think the problem will have to be with my models....
views.py
from django.views.generic import *
from django.core.urlresolvers import reverse_lazy
from .models import Category, Product
class CategoryList(ListView):
model = Category
class CategoryDetail(DetailView):
model = Category
class ProductList(ListView):
model = Product
class ProductDetail(DetailView):
model = Product
class ProductCreate(CreateView):
model = Product
fields = ("category", 'name', 'image', 'description', 'price', 'stock','available', 'negiotiable')
class ProductUpdate(UpdateView):
model = Product
fields = ('name', 'image', 'description', 'price', 'stock','available', 'negiotiable')
class ProductDelete(DeleteView):
model = Product
success_url = reverse_lazy('product_list')
Please let me know what could be done.
Either Add User into list:
class ProductCreate(CreateView):
model = Product
fields = ["category", 'name', 'image', 'description', 'price','stock','available', 'negiotiable', 'user']
OR make sure Field must be null=true and blank=True.
class Product(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='product_created', null=True, blank=True)
Add a form for your product,
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = "__all__"
Also, your user field must be null=True and blank=True.
Then in your create view,
class ProductCreate(CreateView):
model = Product
form_class = ProductForm
def form_valid(self, form):
form.instance.user = self.request.user
form.save()
return super(ProductCreate, self).form_valid(form)
Now, whenever a product is created, the user who created would be added as the user of the product.

Categories

Resources