I am having a circular dependency problem. In order to avoid that I am using
apps.get_model('ModelName')
Is there a way to fetch the serializer class in the same way?
project
app
models
views
serializers
tasks
app_urls
settings
urls
etc etc...
models.py:
from .tasks import taskA
class Bag():
...
sender=Bag
def bag_signal():
taskA()
views:
from .models import Bag
from .serializers import BagSerializer
class BagViewset(ModelViewSet):
model = Bag
serializer = BagSerializer
serializer:
from .models import Bag
class BagSerializer(ModelSerializer):
def meta:
model = Bag
def validate():
**validation stuff
tasks:
from django.apps import apps
def taskA():
model_name = apps.get('app', 'model_name')
model.objects.create(**data)
# wanna call serializer's validate and save it through serializer.save()
Related
I am new with integrating mixpanel to Django backend to track events,As i try to track, it gives me empty brackets anyone with ideas or resources please help me am quite stack
views.py
from django.shortcuts import render
from django.views import View
from rest_framework.generics import ListCreateAPIView
from rest_framework.views import APIView
from rest_framework.response import Response
from .serialize import UserSerializer, TweakSerializer, ChannelSerializer, SubscriberSerializer
from tweaks.models import Tweak
from accounts.models import User
from channels.models import Channel, Subscriber
from mixpanel import Mixpanel
import json
# Create your views here.
mp = Mixpanel('TOKEN')
class userApi(ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request):
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
apiuser=userApi()
point = json.dumps(apiuser.__dict__)
mp.track(point, 'users')
serializers.py
from rest_framework import routers, serializers, viewsets
from django.urls import path, include
from accounts.models import User
from tweaks.models import Tweak
from channels.models import Channel, Subscriber
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = 'username', 'email', 'first_name', 'last_name', 'date_joined'
I am using Django with Django Rest Framework for serializers.
I have the following situation.
In file models.py:
from django.db.models import Manager, Model, CharField
from .serializers import MyModelSerializer
class MyModelManager(Manager):
serializer_class = MyModelSerializer
class MyModel(Model):
name = CharField(max_length=64)
objects = MyModelManager()
In file serializers.py:
from rest_framework.serializers import ModelSerializer
from models import MyModel
class MyModelSerializer(ModelSerializer):
class Meta:
model = MyModel
fields = ('name',)
However, this leads to an import cycle, since both files try to import each other. I could prevent this by making a local import:
class MyModelManager(Manager):
#property
def serializer_class(self):
from ow_articlecode.import_cycle_serializers import MyModelSerializer
return MyModelSerializer
However, this feels like a hack. What would be a proper solution to break this import cycle?
A Manager [Django-doc], has no serializer_class field. In fact a manager does not know anything about serialization. A manager is used to filter, create, etc. objects.
Your models.py thus should look like:
# app/models.py
from django.db.models import Manager, Model, CharField
class MyModelManager(Manager):
# no serializer_class
pass
class MyModel(Model):
name = CharField(max_length=64)
The idea of Models is that this defines your business logic, not the serialization, form, view, template logic.
I have a users app in a Django project (version 2.1 and python 3.6). After an user signup (both front end and when added in the admin dashboard ideally), I'd like to insert data in one other table. I know how to insert data, but I didn't find out how to do it right after a successfull signup.
Ideal answer would just show me how to do something like print('hello') right after an user created his account.
# users/admin.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['email', 'username',]
admin.site.register(CustomUser, CustomUserAdmin)
# users/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = CustomUser
fields = ('username', 'email')
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ('username', 'email')
# users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# add additional fields in here
credit = models.IntegerField(default=200) # editable=False
def __str__(self):
return self.email
# users/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.SignUp.as_view(), name='signup'),
]
# users/views.py
from django.urls import reverse_lazy
from django.views import generic
from .forms import CustomUserCreationForm
class SignUp(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
Use a post-save signal
https://docs.djangoproject.com/en/2.1/ref/signals/
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=User)
def say_hello(sender, instance, **kwargs):
if instate._state.adding:
print('hello')
Signal is better than a method on the view because the User may be created some way other than through the view e.g , via the shell, a management command, a migration, a different view, etc.
Note the _state is not "private" so don't feel bad about using it, it's just named that way to avoid clashing with field names.
Check _state instead of more common checking instance.pk because instance.pk is always present when primary key is a natural key rather than AutoField
I think the best approach would be overriding save method of CustomUser model. For example:
class CustomUser(AbstructUser):
def save(self, *args, **kwargs):
user = super(CustomUser, self).save(*args, **kwargs)
print("Hello World")
return user
Check here in Django documentation for more details: https://docs.djangoproject.com/en/2.1/topics/db/models/#overriding-predefined-model-methods.
i'm new to django. The version i'm using is 1.11.2
I have a a schema like this.
There are many "designs" and each design can have any number of "patterns".
my design model is like below
from django.db import models
from products.models import Product
class Design(models.Model):
name = models.CharField(max_length=200)
product_id = models.ForeignKey(Product, on_delete=models.CASCADE)
price = models.CharField(max_length=200)
def __str__(self):
return self.name
My design serializer is like below
from rest_framework import serializers
from .models import Design
from rest_framework import serializers
from patterns.models import Pattern
class DesignsSerializer(serializers.ModelSerializer):
patterns = DesignPatternSerializer(read_only=True, many=True)
class Meta:
depth = 1
model = Design
fields = ('id','name','patterns')
read_only_fields = ('id','name','patterns')
The view for designs is as below
from django.shortcuts import render
from .models import Design
from .serializers import DesignsSerializer
from rest_framework import generics, filters
# Create your views here.
class ListDesignsByProducId(generics.ListCreateAPIView):
serializer_class = DesignsSerializer
def get_queryset(self):
return Design.objects.filter(product_id__exact = self.kwargs.get('product_id'))
My pattern model is like below.
from django.db import models
from datetime import date
from designs.models import Design
class Pattern(models.Model):
design_id = models.ManyToManyField(Design)
name = models.CharField(max_length=200)
def __str__(self):
return self.name
My pattern serializer is as below
from rest_framework import serializers
from .models import Pattern
class PatternSerializer(serializers.ModelSerializer):
class Meta:
depth = 1
model = Pattern
fields = ('id','design_id','name')
read_only_fields =('id','design_id','name')
Right now the api would return the details of the designs and it's associated products.
I would also like to get an array of patterns associated with the design.
In your DesignsSerializer you referred to the patterns by the name patterns without defining it in your models.
From the Django REST Framework documentation:
You'll normally want to ensure that you've set an appropriate
related_name argument on the relationship, that you can use as the
field name.
In your Pattern model:
class Pattern(models.Model):
design_id = models.ManyToManyField(Design, related_name='patterns')
...
is there any way to show only a list of fields or excluding some of them when using django-rest-framework?
Here's my app/views.py:
from rest_framework.generics import ListAPIView
from .models import PhpbbUsers
class UsersReadView(ListAPIView):
model = PhpbbUsers
Obiously there are some user information that I don't want to show to everyone. How could I do?
Solution code
from rest_framework import generics, serializers
from .models import PhpbbUsers
class UsersSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = PhpbbUsers
fields = ('user_id', 'username', 'user_avatar')
class UsersReadView(generics.ListAPIView):
model = PhpbbUsers
serializer_class = UsersSerializer
Set the serializer_class attribute on the view.
See the quickstart for a good example: http://django-rest-framework.org/tutorial/quickstart.html