Nested model
Nested model¶
Demonstrates a nested serializer: the User model has a foreign key to Company,
and UserSerializer embeds CompanySerializer. Both name fields stream to the
client through a single rx.model declaration.
Backend¶
from rxdjango import ContextChannel, rx, action
from .models import User
from .serializers import UserSerializer
class NestedModelChannel(ContextChannel):
user = rx.model(UserSerializer())
@action
async def authorize(self, password: str):
if password == 'password':
self.user = await User.objects.select_related('company').aget(id=1)
return True
return False
Models¶
from django.db import models
class Company(models.Model):
name = models.CharField(max_length=64)
class User(models.Model):
name = models.CharField(max_length=32)
company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='users')
Serializers¶
from rest_framework import serializers
from nested_model.models import Company, User
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ['id', 'name']
class UserSerializer(serializers.ModelSerializer):
company = CompanySerializer()
class Meta:
model = User
fields = ['id', 'name', 'company']
Frontend¶
import React, { useState } from 'react';
import { useChannel } from '@rxdjango/react';
import { NestedModelChannel } from '../../rx/nested_model/nested_model.channels';
import {
Sections,
Button,
TextInput,
Row,
Note,
} from '../../components/demo';
export function NestedModelDemo() {
const channel = useChannel(NestedModelChannel);
const [password, setPassword] = useState('password');
return (
<Sections>
<div>
<Note>
Authorize with a password to load the user model along with its nested company.
</Note>
<Row>
<TextInput
id="nested-model-password"
label="Password"
value={password}
onChange={setPassword}
/>
<Button
variant="secondary"
onClick={() => channel.authorize(password)}
>
Authorize
</Button>
</Row>
</div>
<div>
{channel.user ? (
<p>
You are user "{channel.user.name}" at "
{channel.user.company._loaded
? channel.user.company.name
: 'Loading…'}"
</p>
) : (
<p>
Enter your password
</p>
)}
</div>
</Sections>
);
}
export default NestedModelDemo;