Задать вопрос

Как менять на странице значения полей ForeignKey и ManyToManyField?

Привет, у меня есть модель Stockroom:
class Stockroom(models.Model):
    head = models.ForeignKey('Person')
    worker = models.ManyToManyField('Person', through='WorkerType')
    goods = models.ManyToManyField('Goods', through='GoodsType')

class WorkerType(models.Model):
    person = models.ForeignKey('Person')
    stockroom = models.ForeignKey('Stockroom')
    type = models.CharField(max_length=150, choices=WORKER_CHOICES, default='NoType')

class GoodsType(models.Model):
    goods = models.ForeignKey('Goods')
    stockroom = models.ForeignKey('Stockroom')
    type = models.CharField(max_length=150, choices=GOODS_CHOICES, default='NoType')
    quantity = models.IntegerField(default=0)


Т.е. у нас есть Склад у которого имеется Начальник, Работники и Товар.
Я бы хотела сделать страничку на которой выводится:
1. Начальник склада, возле него кнопка Поменять, при нажатию на которую идет переход на страничку с возможными кандидатами. Еще кнопка Удалить, на складе может не быть начальника.
2. Работники, которых может быть несколько. Возле них тоже кнопочки Удалить и Поменять. А еще выпадающий список с возможными должностями (type из WorkerType).
3. Товар, тоже самое что и работники, но еще кроме типа товара есть поле Количество товара.

Как сделать View даже не представляю. Единственное что я смогла придумать это наследоваться от UpdateView, но там для head идет выпадающий список, а для worker и goods - список с множественным выбором.

Помогите, пожалуйста, разобраться.
  • Вопрос задан
  • 2741 просмотр
Подписаться 7 Оценить Комментировать
Решения вопроса 1
1. Зачем нужен переход на другую страницу для выбора начальника, разве это удобно? Чтобы избавиться от проблем выпадающего списка при большом количестве записей в таблице Person, можно использовать django-select2 - он даст возможность искать по элементам или, нажав на кнопку "удалить" прямо в элементе управления, указать, что начальника нет. Демо.

2 и 3. С работниками и товарами, наверное, нужно использовать FormSets. Вот пример о том, как скрестить их с class-based views: effectivedjango.com/tutorial/related.html - кажется, он подходит к вашей ситуации.

P. S. Если у вас вся задача состоит в управлении таблицами, не думали для этого использовать родное средство - django-admin? Там всё это уже есть - и выбор, и формсеты. С помощью таких батареек как Django Suit можно облагородить внешний вид. Ну а где нужно - кастомизировать и добавить свои view, скажем, на главную страницу админки.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@tosterru Автор вопроса
Наверное уже мертвый вопрос, но тем не менее, может еще что то посоветуют. Или мне самой еще это когда то понадобится, буду знать где искать.
У меня получилось так:
# forms.py
StockroomWorkerFormSet = inlineformset_factory(Stockroom, WorkerType, extra=0, can_delete=True)
StockroomGoodsFormSet = inlineformset_factory(Stockroom, GoodsType, extra=0, can_delete=True)

# views.py
class StockroomEditView(UpdateView):
    model = Stockroom
    temlate_name = 'stock/edit.html'

    def get_success_url(self):
        return self.get_object().get_absolute_url()

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        worker_formset = self.get_form(StockroomWorkerFormSet)
        goods_formset = self.get_form(StockroomGoodsFormSet)

        return self.render_to_response(self.get_context_data(
            worker_formset=worker_formset, goods_formset=goods_formset))

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        worker_formset = self.get_form(StockroomWorkerFormSet)
        goods_formset = self.get_form(StockroomGoodsFormSet)

    if worker_formset.is_valid() and goods_formset.is_valid():
        return self._form_valid(worker_formset, goods_formset)
    else:
        return self._form_invalid(worker_formset, goods_formset)

    def _form_valid(self, worker, goods):
        worker.save()
        goods.save()
        return HttpResponseRedirect(self.get_success_url())

edit.html
    <form action="" method="post">
        {% csrf_token %}
        {{ worker_formset.management_form }}
        {{ goods_formset.management_form }}
        {% for form in worker_formset %}
            {{ form }}
        {% endfor %}
        {% for form in goods_formset %}
            {{ form }}
        {% endfor %}
    </form>

Если кто то меня слышит, на сколько правильно так делать?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы