Мой вопрос немного длинный из-за недостатка знаний о хороших методах программирования и, прежде всего, о Джанго. Я ценю любые предложения.
Модель (упрощенная)
class Customer(models.Model):
# Customer info
first_name = models.CharField(max_length=75)
last_name = models.CharField(max_length=179, null=True, blank=True)
# ... and more fields that need validation but not needed for the question
pay_method = models.CharField(max_length=1, choices=PAY_METHODS)
bank_code = models.CharField(max_length=4, blank=True, null=True)
bank_office_code = models.CharField(max_length=4, blank=True, null=True)
bank_control_digit = models.CharField(max_length=2, blank=True, null=True)
bank_account_number = models.CharField(max_length=10, blank=True, null=True)
class Product(models.Model):
name = models.CharField(max_length=50)
class Subscription(models.Model):
customer = models.ForeignKey(Customer)
product = models.ForeignKey(Product)
user = models.OneToOneField(User)
# ...
start_date = models.DateField(null=True)
end_date = models.DateField(null=True)
# ...
is_main_subscription = models.BooleanField(default=False)
class Invoice(models.Model):
customer = models.ForeignKey(Customer)
subscriptions = models.ManyToManyField(Subscription,null=True,blank=True)
#...
Проблема
Существует два очень похожих процесса подписки. Один для новых пользователей, а другой для существующих пользователей.
Для новых пользователей процесс подписки включает заполнение персональных данных Клиента и платежной информации в таблице Клиента и создание как минимум одной Подписки. Каждая подписка относится к продукту. В конце процесса создается Счет для всех этих Подписок. Я думаю, что модель Invoice здесь не нужна, но я добавлю ее здесь на случай, если она будет полезна. Каждая подписка имеет пользователя django-contrib-auth для входа в приложение.
Первая подписка - это основная подписка . Пользователь, связанный с этой Подпиской, может продлить или отменить другие подписки и купить новые. Этот новый процесс включает в себя изменение платежной информации, если это необходимо, но не предоставление персональных данных для Клиента И мы должны отличать существующие подписки от новых.
Форма
Для Заказчика я создал три ModelForms:
PaymentForm используется отдельно для зарегистрированных пользователей в процессе подписки
class PaymentForm(forms.ModelForm):
class Meta:
model = Customer
fields = (
'pay_method',
'bank_code',
'bank_office_code',
'bank_control_digit',
'bank_account_number'
)
# ...
DataForm используется отдельно для зарегистрированных пользователей, чья подписка является основной подпиской, для редактирования личной информации Клиента вне процесса подписки.
class DataForm(forms.ModelForm):
class Meta:
model = Customer
fields = (
'first_name',
'last_name',
# All the other fields
)
# ...
NewCustomerForm работал для меня, чтобы создать форму, смешивающую PaymentForm и DataForm
class NewCustomerForm(MyDataForm, PaymentForm):
class Meta:
model = Customer
fields = MyDataForm.Meta.fields + PaymentForm.Meta.fields
Для подписок я думаю, что должно быть два FormSets (встроенные formsets?):
- RenewalsFormSet: для зарегистрированных пользователей, чтобы отменить или возобновить существующие подписки. Пользователь не может редактировать информацию, только отменить или обновить.
- SubscriptionFormSet: для зарегистрированных и незарегистрированных пользователей, для добавления новых подписок.
Как я мог бы обработать оба случая самым простым способом? Новая форма подписки не должна знать о существующих подписках.
И вопрос
Процесс подписки с точки зрения представлений Django будет:
- Просмотр формы GET: Формы предоставляются пользователю.
- POST формы: Формы проверены. Если ошибка: перейдите к пункту 1. В случае успеха: сохраните данные POST в сеансе.
- Просмотр подтверждения GET: Сводка продуктов, которые необходимо приобрести.
- ПОЛУЧИТЕ подтверждение оплаты: В зависимости от выбранного способа оплаты, процесс может отличаться.
- ПОЛУЧИТЕ страницу благодарности
Что я могу сделать, чтобы иметь единый процесс подписки для зарегистрированных и не вошедших пользователей?
Я думал о каком-то объекте, таком как черный ящик, который получает входные данные и возвращает клиента (существующего или нет, в зависимости от того, зарегистрирован ли пользователь) со всеми подписками и пользователями, все они готовы для хранения в базе данных.
Но я не знаю, как это сделать.
(Если вы уже прочитали, значит, вы должны быть очень милы. Спасибо!)