Опросите схему базы данных

Какова лучшая схема базы данных для опросов? Действительно ли связь "один ко многим" хороша для этого? Я думаю о наличии двух таблиц:

poll_questions
    int id
    varchar body
    datetime created_at
    datetime updated_at

poll_answers
    int id
    varchar body
    int votes default 0
    int question_id (foreign key to poll_questions.id)
    datetime created_at
    datetime updated_at

Тогда также была бы третья таблица для отслеживания, кто голосовал за ответ, таким образом, пользователи в состоянии голосовать только однажды:

poll_voting_history
    int id
    int question_id (foreign key to poll_questions.id)
    int answer_id (foreign key to poll_answers.id)
    int user_id (foreign key to the id in the users table)
    datetime created_at
    datetime updated_at

Каковы Ваши мысли? Я думаю об этом право?

23
задан Richard Knop 15 February 2010 в 08:51
поделиться

2 ответа

Вы запускаете его на локальном компьютере, и PHPing подключится к производственному серверу и развернет веб-сайт.:)

-121--4716325-

Я думаю, вам придется добавить здесь новый ModelMultipleChoeyField в PizzaForm и вручную связать это поле формы с полем модели, так как Джанго не сделает этого автоматически для вас.

Следующий фрагмент может быть полезен:

class PizzaForm(forms.ModelForm):
    class Meta:
        model = Pizza

    # Representing the many to many related field in Pizza
    toppings = forms.ModelMultipleChoiceField(queryset=Topping.objects.all())

    # Overriding __init__ here allows us to provide initial
    # data for 'toppings' field
    def __init__(self, *args, **kwargs):
        # Only in case we build the form from an instance
        # (otherwise, 'toppings' list should be empty)
        if kwargs.get('instance'):
            # We get the 'initial' keyword argument or initialize it
            # as a dict if it didn't exist.                
            initial = kwargs.setdefault('initial', {})
            # The widget for a ModelMultipleChoiceField expects
            # a list of primary key for the selected data.
            initial['toppings'] = [t.pk for t in kwargs['instance'].topping_set.all()]

        forms.ModelForm.__init__(self, *args, **kwargs)

    # Overriding save allows us to process the value of 'toppings' field    
    def save(self, commit=True):
        # Get the unsave Pizza instance
        instance = forms.ModelForm.save(self, False)

        # Prepare a 'save_m2m' method for the form,
        old_save_m2m = self.save_m2m
        def save_m2m():
           old_save_m2m()
           # This is where we actually link the pizza with toppings
           instance.topping_set.clear()
           instance.topping_set.add(*self.cleaned_data['toppings'])
        self.save_m2m = save_m2m

        # Do we need to save all changes now?
        if commit:
            instance.save()
            self.save_m2m()

        return instance

Эту PizzaForm можно использовать везде, даже у администратора:

# yourapp/admin.py
from django.contrib.admin import site, ModelAdmin
from yourapp.models import Pizza
from yourapp.forms import PizzaForm

class PizzaAdmin(ModelAdmin):
  form = PizzaForm

site.register(Pizza, PizzaAdmin)

Примечание

Метод save () может быть слишком подробным, но его можно упростить, если не требуется поддерживать ситуацию commit = False , то он будет таким:

def save(self):
  instance = forms.ModelForm.save(self)
  instance.topping_set.clear()
  instance.topping_set.add(*self.cleaned_data['toppings'])
  return instance
-121--891898-

Схема выглядит хорошо, и да, вам также необходимо отслеживать голоса пользователей .

13
ответ дан 29 November 2019 в 02:58
поделиться

Примечание: столбец «голосов» в таблице poll_answers не необходимо. Голоса можно определить, запросив таблицу Poll_voting_history.

5
ответ дан 29 November 2019 в 02:58
поделиться
Другие вопросы по тегам:

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