Skip to main content

reinhardt_views/
mixins.rs

1//! Mixins for common view patterns.
2
3use async_trait::async_trait;
4use reinhardt_core::exception::Result;
5use reinhardt_db::orm::Model;
6use reinhardt_http::Request;
7use serde::Serialize;
8use serde_json::json;
9
10use crate::core::Context;
11
12/// Trait for views that work with multiple objects
13#[async_trait]
14pub trait MultipleObjectMixin<T>: Send + Sync
15where
16	T: Model + Serialize + Send + Sync + Clone,
17{
18	/// Get objects for this view
19	async fn get_objects(&self) -> Result<Vec<T>>;
20
21	/// Get the ordering for the queryset
22	fn get_ordering(&self) -> Option<Vec<String>> {
23		None
24	}
25
26	/// Whether to allow empty result sets
27	fn allow_empty(&self) -> bool {
28		true
29	}
30
31	/// Get the number of items per page
32	fn get_paginate_by(&self) -> Option<usize> {
33		None
34	}
35
36	/// Get the context object name
37	fn get_context_object_name(&self) -> Option<&str> {
38		None
39	}
40
41	/// Build context data for the view
42	fn get_context_data(&self, object_list: Vec<T>) -> Result<Context> {
43		let mut context = Context::new();
44		context.insert("object_list".to_string(), json!(object_list));
45
46		if let Some(name) = self.get_context_object_name() {
47			context.insert(name.to_string(), json!(object_list));
48		}
49
50		Ok(context)
51	}
52}
53
54/// Trait for views that work with a single object
55#[async_trait]
56pub trait SingleObjectMixin<T>: Send + Sync
57where
58	T: Model + Serialize + Send + Sync + Clone,
59{
60	/// Get the slug field name
61	fn get_slug_field(&self) -> &str {
62		"slug"
63	}
64
65	/// Get the primary key URL parameter name
66	fn pk_url_kwarg(&self) -> &str {
67		"pk"
68	}
69
70	/// Get the slug URL parameter name
71	fn slug_url_kwarg(&self) -> &str {
72		"slug"
73	}
74
75	/// Get a single object
76	async fn get_object(&self, request: &Request) -> Result<T>;
77
78	/// Get the context object name
79	fn get_context_object_name(&self) -> Option<&str> {
80		None
81	}
82
83	/// Build context data for the view
84	fn get_context_data(&self, object: T) -> Result<Context> {
85		let mut context = Context::new();
86		context.insert("object".to_string(), json!(object));
87
88		if let Some(name) = self.get_context_object_name() {
89			context.insert(name.to_string(), json!(object));
90		}
91
92		Ok(context)
93	}
94}